Servidor NodeJs para transmissão Laravel Echo com Socket.io.
Os itens a seguir são necessários para funcionar corretamente.
Informações adicionais sobre transmissão com Laravel podem ser encontradas na documentação oficial: https://laravel.com/docs/master/broadcasting
Instale o pacote npm globalmente com o seguinte comando:
$ npm install -g laravel-echo-server
Execute o comando init no diretório do seu projeto:
$ laravel-echo-server init
A ferramenta cli irá ajudá-lo a configurar um arquivo laravel-echo-server.json no diretório raiz do seu projeto. Este arquivo será carregado pelo servidor durante a inicialização. Você pode editar este arquivo posteriormente para gerenciar a configuração do seu servidor.
O Laravel Echo Server expõe uma API http leve para executar a funcionalidade de transmissão. Por motivos de segurança, o acesso a esses endpoints a partir de referenciadores http deve ser autenticado com um ID e chave de APP. Isso pode ser gerado usando o comando cli:
$ laravel-echo-server client:add APP_ID
Se você executar client:add
sem um argumento de id de aplicativo, um será gerado para você. Após executar este comando, o ID e a chave do cliente serão exibidos e armazenados no arquivo laravel-echo-server.json .
Neste exemplo, as solicitações serão permitidas desde que o ID e a chave do aplicativo sejam fornecidos com as solicitações http.
Request Headers
Authorization: Bearer skti68i...
or
http://app.dev:6001/apps/APP_ID/channels?auth_key=skti68i...
Você pode remover clientes com laravel-echo-server client:remove APP_ID
no diretório raiz do seu projeto, execute
$ laravel-echo-server start
no diretório raiz do seu projeto, execute
$ laravel-echo-server stop
Edite a configuração padrão do servidor adicionando opções ao seu arquivo laravel-echo-server.json .
Título | Padrão | Descrição |
---|---|---|
apiOriginAllow | {} | Configuração para permitir que a API seja acessada via CORS. Exemplo |
authEndpoint | /broadcasting/auth | A rota que autentica canais privados |
authHost | http://localhost | O host do servidor que autentica canais privados e de presença |
database | redis | Banco de dados usado para armazenar dados que devem persistir, como membros do canal de presença. As opções atualmente são redis e sqlite |
databaseConfig | {} | Configurações para os diferentes drivers de banco de dados Exemplo |
devMode | false | Adiciona registro adicional para fins de desenvolvimento |
host | null | O host do servidor socket.io ex. app.dev . null aceitará conexões em qualquer endereço IP |
port | 6001 | A porta na qual o servidor socket.io deve ser executado |
protocol | http | Deve ser http ou https |
sslCertPath | '' | O caminho para o certificado SSL do seu servidor |
sslKeyPath | '' | O caminho para a chave SSL do seu servidor |
sslCertChainPath | '' | O caminho para a cadeia de certificados SSL do seu servidor |
sslPassphrase | '' | A frase secreta a ser usada para o certificado (se aplicável) |
socketio | {} | Opções para passar para a instância socket.io (opções disponíveis) |
subscribers | {"http": true, "redis": true} | Permite desabilitar assinantes individualmente. Assinantes disponíveis: http e redis |
Se um arquivo .env for encontrado no mesmo diretório que o arquivo laravel-echo-server.json, as seguintes opções podem ser substituídas:
authHost
: LARAVEL_ECHO_SERVER_AUTH_HOST
Nota : Esta opção retornará à opção LARAVEL_ECHO_SERVER_HOST
como padrão se estiver definida no arquivo .env.host
: LARAVEL_ECHO_SERVER_HOST
port
: LARAVEL_ECHO_SERVER_PORT
devMode
: LARAVEL_ECHO_SERVER_DEBUG
databaseConfig.redis.host
: LARAVEL_ECHO_SERVER_REDIS_HOST
databaseConfig.redis.port
: LARAVEL_ECHO_SERVER_REDIS_PORT
databaseConfig.redis.password
: LARAVEL_ECHO_SERVER_REDIS_PASSWORD
protocol
: LARAVEL_ECHO_SERVER_PROTO
sslKeyPath
: LARAVEL_ECHO_SERVER_SSL_KEY
sslCertPath
: LARAVEL_ECHO_SERVER_SSL_CERT
sslPassphrase
: LARAVEL_ECHO_SERVER_SSL_PASS
sslCertChainPath
: LARAVEL_ECHO_SERVER_SSL_CHAIN
Observação: atualmente, esta biblioteca oferece suporte apenas para veiculação de http ou https, não de ambos.
Se você está lutando para implementar o SSL com este pacote, você pode usar um módulo proxy no Apache ou NginX. Essencialmente, em vez de conectar o tráfego do seu websocket a https://yourserver.dev:6001/socket.io?..... e tentar protegê-lo, você pode conectar o tráfego do seu websocket a https://yourserver.dev/socket .io. Nos bastidores, o módulo proxy do Apache ou NginX será configurado para interceptar solicitações para /socket.io e redirecioná-las internamente para o seu servidor de eco por meio de não SSL na porta 6001. Isso mantém todo o tráfego criptografado entre o navegador e a web. servidor, pois seu servidor web ainda fará a criptografia/descriptografia SSL. A única coisa que fica insegura é o tráfego entre o seu servidor web e o servidor Echo, o que pode ser aceitável em muitos casos.
#the following would go within the server{} block of your web server config
location /socket.io {
proxy_pass http://laravel-echo-server:6001; #could be localhost if Echo and NginX are on the same box
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
RewriteCond %{REQUEST_URI} ^/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) ws://localhost:6001/$1 [P,L]
ProxyPass /socket.io http://localhost:6001/socket.io
ProxyPassReverse /socket.io http://localhost:6001/socket.io
O diretório de trabalho no qual laravel-echo-server
irá procurar pelo arquivo de configuração laravel-echo-server.json
pode ser passado para o comando start
através do parâmetro --dir
assim: laravel-echo-server start --dir=/var/www/html/example.com/configuration
O Laravel Echo Server assina eventos recebidos com dois métodos: Redis e Http.
Seu aplicativo principal pode usar o Redis para publicar eventos em canais. O Laravel Echo Server irá assinar esses canais e transmitir essas mensagens via socket.io.
Usando Http, você também pode publicar eventos no Laravel Echo Server da mesma forma que faria com o Redis, enviando um channel
e message
para o endpoint de transmissão. Você precisa gerar uma chave de API conforme descrito na seção Clientes de API e fornecer a chave de API correta.
Solicitar ponto final
POST http://app.dev:6001/apps/your-app-id/events?auth_key=skti68i...
Corpo da Solicitação
{
"channel" : " channel-name " ,
"name" : " event-name " ,
"data" : {
"key" : " value "
},
"socket_id" : " h3nAdb134tbvqwrg "
}
canal - O nome do canal para o qual transmitir um evento. Para canais privados ou de presença, acrescente private-
ou presence-
. canais - Em vez de um único canal, você pode transmitir para vários canais com uma solicitação. name - Uma string que representa a chave do evento em seu aplicativo. data - Dados que você gostaria de transmitir para o canal. socket_id (opcional) – O ID do soquete do usuário que iniciou o evento. Quando presente, o servidor irá apenas "transmitir para outros".
O assinante HTTP é compatível com o assinante Laravel Pusher. Basta configurar o host e a porta do seu servidor Socket.IO e definir o ID e a chave do aplicativo em config/broadcasting.php. O segredo não é obrigatório.
' pusher ' => [
' driver ' => ' pusher ' ,
' key ' => env ( ' PUSHER_KEY ' ),
' secret ' => null ,
' app_id ' => env ( ' PUSHER_APP_ID ' ),
' options ' => [
' host ' => ' localhost ' ,
' port ' => 6001 ,
' scheme ' => ' http '
],
],
Agora você pode enviar eventos usando HTTP, sem usar Redis. Isso também permite que você use a API Pusher para listar canais/usuários conforme descrito na biblioteca Pusher PHP
A API HTTP expõe endpoints que permitem coletar informações sobre o servidor e os canais em execução.
Status Obtenha o número total de clientes, tempo de atividade do servidor e uso de memória.
GET /apps/:APP_ID/status
Canais Lista de todos os canais.
GET /apps/:APP_ID/channels
Canal Obtenha informações sobre um canal específico.
GET /apps/:APP_ID/channels/:CHANNEL_NAME
Usuários do canal Lista de usuários em um canal.
GET /apps/:APP_ID/channels/:CHANNEL_NAME/users
O acesso entre domínios pode ser especificado no arquivo laravel-echo-server.json alterando allowCors
em apiOriginAllow
para true
. Você pode então definir o CORS Access-Control-Allow-Origin, Access-Control-Allow-Methods como uma string separada por vírgula (GET e POST são habilitados por padrão) e os Access-Control-Allow-Headers que a API pode receber.
Exemplo abaixo:
{
"apiOriginAllow" :{
"allowCors" : true ,
"allowOrigin" : " http://127.0.0.1 " ,
"allowMethods" : " GET, POST " ,
"allowHeaders" : " Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-Id "
}
}
Isso permite que você envie solicitações à API via AJAX de um aplicativo que pode estar em execução no mesmo domínio, mas em uma porta diferente ou em um domínio totalmente diferente.
Para persistir os dados do canal de presença, há suporte para uso de Redis ou SQLite como armazenamento de chave/valor. A chave é o nome do canal e o valor é a lista de membros do canal de presença.
Cada driver de banco de dados pode ser configurado no arquivo laravel-echo-server.json na propriedade databaseConfig
. As opções são repassadas ao provedor do banco de dados, para que os desenvolvedores sejam livres para configurá-las como desejarem.
Por exemplo, se você quiser passar uma configuração personalizada para o Redis:
{
"databaseConfig" : {
"redis" : {
"port" : " 3001 " ,
"host" : " redis.app.dev " ,
"keyPrefix" : " my-redis-prefix "
}
}
}
Nota: Nenhum esquema (http/https etc) deve ser usado para o endereço do host
Uma lista completa de opções do Redis pode ser encontrada aqui.
Por exemplo, se você quiser usar o redis-sentinel, precisará passar uma configuração personalizada:
"databaseConfig" : {
"redis" : {
"sentinels" : [
{
"host" : " redis-sentinel-0 " ,
"port" : 26379
},
{
"host" : " redis-sentinel-1 " ,
"port" : 26379
}
{
"host" : " redis-sentinel-2 " ,
"port" : 26379
}
],
"name" : " mymaster " ,
"sentinelPassword" : " redis-password "
},
},
Para obter mais informações sobre a configuração do Redis Sentinel, você pode verificar isto
Com SQLite você pode estar interessado em alterar o caminho onde o banco de dados está armazenado.
{
"databaseConfig" : {
"sqlite" : {
"databasePath" : " /path/to/laravel-echo-server.sqlite "
}
}
}
Nota 1: O caminho é relativo à raiz do seu aplicativo, não ao seu sistema.
Nota 2: node-sqlite3 é necessário para este banco de dados. Instale antes de usar.
npm install sqlite3 -g
Quando os usuários ingressam em um canal de presença, os dados de autenticação do canal de presença são armazenados usando o Redis.
Embora os canais de presença contenham uma lista de usuários, haverá casos em que um usuário ingressará em um canal de presença diversas vezes. Por exemplo, isso ocorreria ao abrir várias guias do navegador. Nesta situação, os eventos de “entrada” e “saída” são emitidos apenas para a primeira e última instância do usuário.
Opcionalmente, você pode configurar o laravel-echo-server para publicar um evento em cada atualização em um canal de presença, definindo databaseConfig.publishPresence
como true
:
{
"database" : " redis " ,
"databaseConfig" : {
"redis" : {
"port" : " 6379 " ,
"host" : " localhost "
},
"publishPresence" : true
}
}
Você pode usar a integração Redis do Laravel para acionar o código do aplicativo a partir daí:
Redis :: subscribe ([ ' PresenceChannelUpdated ' ], function ( $ message ) {
var_dump ( $ message );
});
Veja a documentação oficial do Laravel para mais informações. https://laravel.com/docs/master/broadcasting#introduction
Você pode incluir a biblioteca cliente socket.io do seu servidor em execução. Por exemplo, se o seu servidor estiver rodando em app.dev:6001
você poderá adicionar uma tag de script ao seu html da seguinte forma:
<script src="//app.dev:6001/socket.io/socket.io.js"></script>
Nota: Ao usar a biblioteca cliente socket.io do seu servidor em execução, lembre-se de verificar se a variável global io
está definida antes de assinar os eventos.
µWebSockets foi oficialmente descontinuado. Atualmente não há suporte para µWebSockets no Socket.IO, mas pode ter o novo suporte ClusterWS chegando. Enquanto isso, o Laravel Echo Server usará o mecanismo ws
por padrão até que haja outra opção.