Olá, estou com o seguinte cenário, implementei um chat utilizando websockets, o chat server roda com Swoole (Swoole\WebSocket\Server), tive alguns problemas ao colocar em produção por conta do SSL (HTTPS, WSS), mas consegui contornar isso configurando os certificados SSL no objeto Server do Swoole, conforme o código abaixo:
$servidor = new Server($host, $port, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
$servidor->set([
'ssl_cert_file' => DIR_CERT_SSL."/fullchain.pem",
'ssl_key_file' => DIR_CERT_SSL."/privkey.pem"
]);
As conexões realizadas via navegador (front-end) com javascript funcionam 100%, tudo dentro do esperado.
No entanto, surgiu a necessidade de enviar mensagens no lado do servidor para os clientes conectados. Pesquisei nos fóruns e na documentação do Swoole e encontrei essa implementação no github , que utiliza uma instância do \Swoole\Client(SWOOLE_SOCK_TCP)
...
function __construct($host, $port, $path = '/', $origin = null)
{
$this->host = $host;
$this->port = $port;
$this->path = $path;
$this->origin = $origin;
$this->key = $this->generateToken(self::TOKEN_LENGHT);
}
public function connect()
{
$this->socket = new \Swoole\Client(SWOOLE_SOCK_TCP);
if (!$this->socket->connect($this->host, $this->port)) {
return false;
}
$this->socket->send($this->createHeader());
return $this->recv();
}
...
Eu instancio essa classe e chamo o método send, passando como parâmetro a mensagem que eu quero enviar, funciona 100% localmente sem o uso de SSL (WSS, HTTPS)
Exemplo:
$w = new WebSocketClient('localhost', 123456);
$w->connect();
$w->send("Olá mundo!");
$w->disconnect();
Mas quando rodo em produção, retonar a seguinte mensagem no terminal do servidor websocket:
WARNING Socket::ssl_accept(): bad SSL client[127.0.0.1:58308], reason=252, error_string=unknown protocol
Tentei solucionar alterando o método connect() da classe WebSocketClient adicionando no parâmetro a variável global SWOOLE_SSL :
public function connect()
{
$this->socket = new \Swoole\Client(SWOOLE_SOCK_TCP | SWOOLE_SSL);
if (!$this->socket->connect($this->host, $this->port)) {
return false;
}
$this->socket->send($this->createHeader());
return $this->recv();
}
Desta forma não ocorre mais o erro, mas o algoritmo entra em loop infinito e começa a disparar a mesma mensagem várias vezes para todos os usuários conectados.
Não sei se estou utilizando a melhor abordagem para resolver essa questão, quem já passou por isso e puder auxiliar no envio de mensagens via websockets no lado do servidor agradeço.
Grato!