Closed sigridslima closed 4 years ago
@sigridslima
Isso funciona para mim perfeitamente.
https://github.com/ZeusAutomacao/DFe.NET/issues/822#issuecomment-415055885
A questão foi completamente resolvida somente com a aplicação de console fazendo o processo, foi tentado tudo que está documentado na biblioteca.
O que foi tentado (que eu lembro):
Expect100Continue SecurityProtocol Deixar sem senha Using (para chamar o dispose) Manter em cache O problema também se repete no uso de outras bibliotecas (no meu caso com o ACBr.Net.CTe).
A solução encontrada foi o console application sendo fechado no final de cada requisição.
https://github.com/ZeusAutomacao/DFe.NET/issues/822#issuecomment-474361948
Esse erro é antigo aqui, eu cheguei a migrar meu CTe para o ACBr e acontecia a mesma coisa.
Talvez trabalhar com Thread e matar a segunda thread que faz o consumo da biblioteca seja a unica coisa que não tentei a fundo, mas sinceramente eu nem tentaria, usa a solução acima que é sucesso.
Então como poderia implementar o codigo do console do amigo?
static void Main(string[] args) { string metodo = string.Empty; string id = string.Empty; string empresa = string.Empty; string acesso = string.Empty; string justificativa = string.Empty;
try
{
metodo = args[0];
id = args[1];
empresa = args[2];
acesso = args[3];
GArquivos.GravarLog($"ZeusApplication: {JsonConvert.SerializeObject(args)}");
ConfigLocal.LerConfiguracoes();
using (var conexao = new Conexao(_poolConnection: false))
{
new SistemaDAL(conexao).Load();
new ConfiguracoesDAL(conexao).Load();
Globals.DadosEmpresa = new EmpresaDAL(conexao).Load(int.Parse(empresa));
AcessoBO.AcessoAtual = new AcessoDAL(conexao).Load(int.Parse(acesso));
}
switch (metodo.ToLower())
{
case "nfe_transmitir":
bool forcarOffline = string.Equals(args[4].ToLower(), "true");
new GDFe().Transmitir(long.Parse(id), forcarOffline);
break;
case "nfe_transmitir_lote":
new GDFe().TransmitirLote(id);
break;
case "nfe_consultar": new GDFe().Consultar(long.Parse(id)); break;
case "nfe_cancelar":
justificativa = args[4];
new GDFe().Cancelar(long.Parse(id), justificativa);
break;
case "nfe_cartacorrecao":
string jsonCarta = GArquivos.CombinarDiretorio(Environment.CurrentDirectory, "temp", "carta_correcao.json");
jsonCarta = GArquivos.LerArquivoTexto(jsonCarta);
GArquivos.GravarLog(jsonCarta);
new GDFe().CartaCorrecao(jsonCarta);
break;
case "cte_transmitir": new GCTe().Transmitir(long.Parse(id)); break;
case "cte_transmitir_lote": new GCTe().TransmitirLote(id); break;
case "cte_consultar": new GCTe().Consultar(long.Parse(id)); break;
case "cte_cancelar":
justificativa = args[4];
new GCTe().Cancelar(long.Parse(id), justificativa);
break;
case "mdfe_transmitir": GMDFe.Transmitir(long.Parse(id)); break;
case "mdfe_consultar": GMDFe.Consultar(long.Parse(id)); break;
case "mdfe_encerrar": GMDFe.Encerrar(long.Parse(id)); break;
case "mdfe_cancelar":
justificativa = args[4];
GMDFe.Cancelar(long.Parse(id), justificativa);
break;
default:
throw new Exception("Método não suportado");
}
}
catch (Exception ex)
{
string PathZeus = GArquivos.CombinarDiretorio(AppDomain.CurrentDomain.BaseDirectory, "temp", "resposta.txt");
string strLog = $"Zeus Console [Método: {metodo}] [Id: {id}] [Empresa:{empresa}] [Acesso:{acesso}]{Environment.NewLine}" +
$"Erro: {ex.Message}{Environment.NewLine}" +
$"Inner: {ex.InnerException}{Environment.NewLine}" +
$"StackTrace: {ex.StackTrace}";
GArquivos.GravarLog(strLog);
GArquivos.ExcluirArquivo(PathZeus);
GArquivos.EscreverTexto(PathZeus, strLog);
}
finally
{
GArquivos.GravarLog($"Finalizando ZeusApplication");
}
}
@sigridslima
A implementação é bem tranquila, porque na teoria seu código já está pronto.
Vamos usar como exemplo o transmitir.
o seu método Transmitir(objetonfe)
que você já tem na sua aplicação você colocaria no console e na aplicação você chamaria o console passando os atributos... neste comentário https://github.com/ZeusAutomacao/DFe.NET/issues/822#issuecomment-474361948 tem até o exemplo de chamada....
var process = new Process();
process.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "GereneSI.Zeus.Console.exe");
process.StartInfo.Arguments = $"NFE_TRANSMITIR {gnfe.Id} {Globals.DadosEmpresa.Codigo} {AcessoBO.AcessoAtual.Codigo} {(forcarOffline ? "true" : "false")}";
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.Start();
process.WaitForExit();
Eu passo o método "NFE_TRANSMITIR" ou como você quiser chamar, passo o Id da nota no banco, porque depois eu carrego ele e passo algumas outas coisas que minha aplicação precisa como o Id da empresa logada, o código do acesso atual (para eu pegar o usuário atual e gerar logs).
Feito isso é só chamar o método...
static void Main(string[] args)
{
string metodo = string.Empty;
string id = string.Empty;
string empresa = string.Empty;
string acesso = string.Empty;
string justificativa = string.Empty;
try
{
//aqui são os argumentos, você coloca quantos precisar...
metodo = args[0];
id = args[1];
empresa = args[2];
acesso = args[3];
//aqui gravo o log da chamada
GArquivos.GravarLog($"ZeusApplication: {JsonConvert.SerializeObject(args)}");
//regras de negócio do meu sistema ....
ConfigLocal.LerConfiguracoes();
using (var conexao = new Conexao(_poolConnection: false))
{
new SistemaDAL(conexao).Load();
new ConfiguracoesDAL(conexao).Load();
Globals.DadosEmpresa = new EmpresaDAL(conexao).Load(int.Parse(empresa));
AcessoBO.AcessoAtual = new AcessoDAL(conexao).Load(int.Parse(acesso));
}
switch (metodo.ToLower())
{
case "nfe_transmitir":
//chama seu método de transmitir!
new GDFe().Transmitir(long.Parse);
break;
case ... //outros métodos...
default:
throw new Exception("Método não suportado");
}
}
catch (Exception ex)
{
//tratamento
}
}
EU faço assim e para mim funciona.
Ola, infelizmente apresentou o mesmo erro, fiz somente uma rotina de conexao com o serviço, porem quando ele fica ocioso por três (3)minutos, exatamente 2:55 eu cronometrei, ele apresenta o erro, mas conseguir contornar com uma repetição a cada 1:30 ele se comunica com os servidores da Sefaz, sei que não e um pratica boa pois sempre ficará fazendo uma requisição. Mas ireir tentar outras praticas por aqui.
class Program { private const string ArquivoConfiguracao = @"\configuracao.xml"; static ConfiguracaoApp _configuracoes; static void Main(string[] args) { for (int i = 0; i <= 1000; i++) { //carregar configuração var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
_configuracoes = !File.Exists(path + ArquivoConfiguracao)
? new ConfiguracaoApp()
: FuncoesXml.ArquivoXmlParaClasse<ConfiguracaoApp>(path + ArquivoConfiguracao);
if (_configuracoes.CfgServico.TimeOut == 0)
_configuracoes.CfgServico.TimeOut = 3000; //mínimo
///
try
{
#region Status do serviço
var servicoNFe = new ServicosNFe(_configuracoes.CfgServico);
var retornoStatus = servicoNFe.NfeStatusServico();
#endregion
Console.WriteLine("Serviço Online");
Console.ReadKey();
}
catch (Exception ex)
{
if (!string.IsNullOrEmpty(ex.Message))
//MessageBox.Show(ex.Message, "Erro Geral");
Console.WriteLine("Sem Conexao");
Console.ReadKey();
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
}
}
}
}
@sigridslima
Eu sinceramente não entendi o seu cenário...
Da forma como te passe a aplicação "morre" depois de cada chamada, não existe a possibilidade de acontecer erros por inatividade.
Então fiz como foi citado acima mas apresentou o mesmo erro depois de um tempo ocioso.
1º Criei o console com minha chamada de verificação de serviço.
var servicoNFe = new ServicosNFe(_configuracoes.CfgServico);
var retornoStatus = servicoNFe.NfeStatusServico();
#endregion
Console.WriteLine("Serviço Online");
Console.ReadKey();
2º No aplicativo tenho a chamada do console
var process = new Process(); process.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ConsoleA3.exe"); // process.StartInfo.Arguments = $"NFE_TRANSMITIR {gnfe.Id} {Globals.DadosEmpresa.Codigo} {AcessoBO.AcessoAtual.Codigo} {(forcarOffline ? "true" : "false")}"; process.StartInfo.CreateNoWindow = true; process.StartInfo.UseShellExecute = false; process.Start(); process.WaitForExit();
Peço por gentileza por favor que analise onde errei. Obrigado
@sigridslima
Não consigo analisar seu código assim, mas a teoria está correta.
Entretanto, o problema da "inatividade" não existiria porque o console "morre" sempre, cada requisição seria sempre uma requisição "nova" em uma aplicação que acabou de nascer.
@sigridslima conseguiu resolver ou ainda esta com o problema?
Como pode ver nessa pesquisa do google Esse erro é algo recorrente por outros usuários de outros sistemas e frameworks. Acredito que por isso seja uma falha a nível abaixo do framework Zeus. Uma das dicas que pesquisei foi a utilização do tls 1.2 e o uso de um FOR de tentativa de pelo menos 5 vezes...
@sigridslima nas configurações do NFE tenta colocar o seguinte codigo:
ValidarCertificadoDoServidor = false,
Ainda não conseguir solucionar, fiz um paliativo de 2 em 2 minutos faz uma requisição para ver se esta online o serviço, ai nao apresentou o problema nao, mas quando fica offline e passa dos 3 minutos apresenta o erro ai tenho que reiniciar a aplicação, Vou tentar fazer um for para ver. obrigado
Essa Issue foi marcada automáticamente como obsoleta, devido a um longo periodo de inatividade. Se nenhuma interação ocorrer nos próximos dias, ela será encerrada. Agradecemos a sua contribuição, esse processo é apenas para manter o repositório mais organizado.
Pessoal sei q já foram abertos vários tópicos porem nenhum foi conclusivo e não sanou meu problema. Então esse erro só acontece com os clientes que possuem o certificado A3, Quando o sistema fica ocioso ele apresenta isso, as vezes troco o protocolo TLS12 para TLS depois vice versa por varias tentativas ai funciona, mas na maioria das vezes tenho q reiniciar a aplicação, e outro problema também que percebi é quando altero a emissão de NF-e para emitir NFC-e e vice versa, também apresenta o erro, ai só a reinicialização do aplicativo. Ja o com certificado A1 não tenho esse problema emito notas simultaneamente inclusive via rede. Aguardo a colaboração de alguém.