EvolutionAPI / evolution-api

Evolution API is an open-source WhatsApp integration API
https://evolution-api.com
Other
1.88k stars 1.02k forks source link

Problemas ao conectar Websocket - Socket hang up #741

Open stenioanibal opened 3 months ago

stenioanibal commented 3 months ago

Welcome!

What did you do?

Estou estudando um pouco sobre o projeto. Já fiz diversos testes aqui e tudo corre tranquilamente, exceto pelo websocket.

Fiz a instalação seguindo a documentação, porém, não consegui obter nenhum erro nos logs que justifique o fato do retorno de bad gateway.

Nos logs do NGINX, obtenho o seguinte:

upstream prematurely closed connection while reading response header from upstream

Testei tanto como global events quanto o específico da instância. As tentativas de conexão estão sendo realizadas no Postman.

As configurações do env foram implementadas seguindo o vídeo de instruções acerca delas, incluindo o URL (domínio da aplicação) e SSL_CONF (certificados funcionais gerados via certbot) quando aplicáveis.

What did you expect?

Conexão do websocket funcional conforme apresenta a documentação.

What did you observe instead of what you expected?

Em todos os testes, criei uma máquina com Ubuntu limpo e segui apenas a documentação, sem quaisquer demais configurações.

Ao tentar conectar pelo domínio configurado no NGINX, o retorno é o seguinte:

Error: Unexpected server response: 502

Para verificar se não seria relativo ao NGINX, os testes executados diretamente no IP:PORTA retornam o seguinte:

Socket hang up

Screenshots/Videos

No response

Which version of the API are you using?

v1.8.1, v1.8.2 e v2.0.6-rc

What is your environment?

Linux

Other environment specifications

No response

If applicable, paste the log output

No response

Additional Notes

Mesmo com a configuração para obter os logs incluindo verbose, nada é retornado relativo a tentativa de conexão realizada.

A documentação não dá mais detalhes sobre a configuração para o funcionamento do websocket, portanto, espera-se que funcione sem outras dependências.

fabioselau077 commented 3 months ago

Aqui mesma coisa, utilizando nginx também

member3541 commented 3 months ago

Estou com mesmo problema, já fiz de tudo e não funcionou

DavidsonGomes commented 3 months ago

Preciso de mais informações, como esta tentando acessar o websocket?

stenioanibal commented 3 months ago

Fala galera. Descobri qual é o problema, algo bem ridículo, diga-se de passagem.

A Evolution utiliza o Socket.io e, neste caso, o websocket não opera no protocolo tradicional (ws), mas sim pelo do próprio Socket.io (veja na documentação).

Com isso, para testar no Postman, basta selecionar a opção Socket.io ao invés de Websocket (vide imagem). Para o client side, utilize a própria biblioteca para realizar a conexão e comunicação.

Sendo assim, a configuração no Postman deve ficar conforme o print abaixo:

image

Aproveitando, @DavidsonGomes, creio que possa ser válida a análise da necessidade do uso do Socket.io para a comunicação dos Websockets, conforme demonstra esse comparativo. Utilizar o protocolo do Websocket nativo pode trazer mais interoperabilidade, além de um pequeno ganho de performance.

member3541 commented 3 months ago

vc pode colocar uma demonstração aqui de como conectar ?, eu fiz seguindo a doc não consegui fazer funcionar

member3541 commented 3 months ago

pareçe que descobri algo tambem, esta dando erro de cors mesmo liberando para todos dominios rodar o socket

stenioanibal commented 3 months ago

Estou realizando um debug para identificar os problemas e implementar as correções. De acordo com os meus testes, temos o seguinte cenário:

Para replicar, basta seguir os passos abaixo:

Hoje terei mais novidades e daí, trago aqui e também em um pull request.

stenioanibal commented 3 months ago

pareçe que descobri algo tambem, esta dando erro de cors mesmo liberando para todos dominios rodar o socket

Isso é relativo ao formato da configuração no Socket.io. Conforme a documentação, para a opção *, não deve ser passado como array, o que não possui um tratamento atualmente conforme a imagem a seguir (código da v2 mas, vale para as anteriores).

image

Vou incluir isso no pull request.

stenioanibal commented 3 months ago

Para instâncias criadas via API, a conexão ocorre normalmente, sendo apenas necessário ter atenção ao seguinte:

Em versões anteriores a 2.0, os parâmetros seguem o formato snake case (opcao_com_underline), sendo que a partir da 2.0 o padrão é CamelCase (opcaoSemUnderline).

Tendo isso em mente, ao criar uma instância via API, a conexão ao websocket específico da mesma não apresentará o erro invalid namespace e ocorrerá normalmente.

Já em instâncias criadas manualmente, mesmo após ativar o websocket nas configurações, o erro invalid namespace ocorre até alguma das ações que afeta a execução da instância, conforme mencionado anteriormente.

stenioanibal commented 3 months ago

Basicamente, o problema ocorre apenas quando a instância é criada pelo manager. Especificamente na v2.0, um problema adicional, mas também relativo ao websocket, ocorre na edição de qualquer opção, após salvar ativando as configurações uma vez. Ao tentar ativar outros eventos ou desativar qualquer opção, as alterações não são salvas.

Para replicar, basta seguir os passos:

Creio que o @DavidsonGomes possa nos ajudar aqui a resolver esses dois problemas (o citado acima e a impossibilidade de conectar ao websocket em uma instância criada manualmente). Fiz alguns testes e debugs, porém, não encontrei nenhum ponto para justificar isso.

Lembrando que, o problema da conexão ao websocket em instâncias novas criadas manualmente ocorrem tanto na v2.0 quanto na v1.8.2 e v1.8.1.

Quanto ao CORS, vou fazer o pull request agora.

stenioanibal commented 3 months ago

@DavidsonGomes, seguem os detalhes para a correção do CORS no websocket. Não pude abrir um pull request por não ter a role de contributor.


Conforme exibe a documentação do Socket.io, para o CORS *, o mesmo não deve ser passado como array.

Para corrigir o problema, basta alterar a linha 17 do arquivo src/api/integrations/websocket/libs/socket.server.ts, conforme exibido abaixo:

const cors = configService.get<Cors>('CORS').ORIGIN;

export const initIO = (httpServer: Server) => {
  if (configService.get<Websocket>('WEBSOCKET')?.ENABLED) {
    io = new SocketIO(httpServer, {
      cors: {
        origin: cors.includes('*') ? '*' : cors, // Retorna apenas a string quando a configuração contêm '*'
      },
    });

   ...

O problema ocorre tanto na v2.0 quanto nas anteriores.