3
respostas

Swoole e WebSocket - Mensagens Privadas

Assisti ao vídeo do Vinícius Dias no YouTube (Swoole PHP: Criando um servidor de WebSocket https://www.youtube.com/watch?v=GCECSLtT49U). Queria uma ideia de como tornar o chat privado, separando em salas que podem ter várias pessoas em cada uma.

No evento 'on message' seria sempre que recebe mensagem ele age. Em $mensagem->fd tem o id de quem enviou a msg.

Usaria o evento 'on open' para pegar o ID de quem acabou de se conectar? e 'on close' para pegar o id e remove-lo quando ele desconectar?

Pensei em pegar esses IDs e salvar em um DB por exemplo atrelando eles a salas especificas.

Daí acho que ao invés de fazer o foreach em $servidor->connections, pegaria a sala ao qual o id de origem da msg pertence, e buscaria os demais IDs que fazem parte da mesma sala, fazendo o loop e enviando a msg para eles, exceto para o id de origem conforme no exemplo.

Sobre o 'on open' e 'on close', se no mesmo navegador abrir múltiplas abas, cada aba seria uma nova conexão com novo ID ou o mesmo ID?

Se for, quando desconectar clicando em um botão Sair em uma aba, para sair em todas as demais, deveria atrelar todos estes IDs a um único token de sessão por exemplo, para entender que o usuário quis deslogar-se, e assim, finalizar as conexões de todas as abas.

Estas ideias dariam certo?

Grata

3 respostas

Usaria o evento 'on open' para pegar o ID de quem acabou de se conectar? e 'on close' para pegar o id e remove-lo quando ele desconectar?

É exatamente como eu faria. Aí eu ligaria esse ID à sala em questão. Aí você pode armazenar esses relacionamentos das salas em Tables do Swoole (https://www.swoole.co.uk/docs/modules/swoole-table) ou em algum armazenamento externo como Redis.

Sobre o 'on open' e 'on close', se no mesmo navegador abrir múltiplas abas, cada aba seria uma nova conexão com novo ID ou o mesmo ID?

Cada nova conexão gera um novo ID. Você pode enviar alguma informação do cliente (como um token) para o servidor e dessa forma não depender apenas do ID da conexão. Assim várias Abas podem ver o mesmo chat, se preferir.

Se for, quando desconectar clicando em um botão Sair em uma aba, para sair em todas as demais, deveria atrelar todos estes IDs a um único token de sessão por exemplo, para entender que o usuário quis deslogar-se, e assim, finalizar as conexões de todas as abas.

Exatamente. :-D

Vinicius, o que acha dessa ideia. Será que é possível?

Passar parâmetros adicionais no $mensagem->fd na hora que cada novo cliente se conecta?

Encontrei as informações abaixo neste tutorial https://dev.to/ronieneubauer/websocket-em-php-sim-e-possivel-9gm que parece bem bom "Por padrão o swoole usa um inteiro incremental iniciando de 1 ->getClientInfo($fd): Retorna um array com as informações do FD fornecido."

o ID gerado pelo Swoole poderia ser manipulado na hora que ele grava?

Exemplo: adicionaria o nome de uma sala no inicio ou final

sala12-IdGeradoAutomaticamentepeloSwoole

A partir dai usaria o que tem antes do hifen(-) para determinar quem da lista de $fd receberia a mensagem.

Ou ainda pensei na seguinte possibilidade usando este detalhe ->getClientInfo($fd): Retorna um array com as informações do FD fornecido."

Salvar na hora que conecta ao Socket, a sala e tbm um hash que identifica o cliente neste array com as informações do FD.

Clientes da mesma sala trocariam mensagens. e pelo hash do cliente, caso ele tivesse múltiplas abas abertas, ao solicitar a desconexão em uma delas, sairia em todas abas.

Desde já agradeço

Milene, fiquei um pouco confuso nas suas dúvidas, mas o que eu faria: Ao me conectar a uma sala, enviaria uma mensagem pro servidor informando a sala em questão. Assim no servidor eu ligaria o fd com a sala. É uma abordagem relativamente simples.