WebSocketServer
A classe WebSocketServer
permite-lhe criar e configurar um servidor WebSocket em 4D. Quando o servidor 4D WebSocket estiver ativo, você poderá abrir e usar conexões WebSocket entre o 4D e os clientes usando a classe WebSocketConnection
.
História
Release | Mudanças |
---|---|
20 | Adicionado |
O protocolo WebSocket proporciona um canal de comunicação full-duplex entre um servidor WebSocket e um cliente (por exemplo, um navegador Web). Para obter mais informações sobre servidores WebSocket, leia esta página na Wikipedia.
Consulte também esta postagem no blog sobre o servidor 4D WebSocket.
Requisitos
Para criar e manipular seu servidor WebSocket em 4D, é preciso usar duas classes embutidas em 4D:
- essa classe (
4D.WebSocketServer
) para gerenciar o próprio servidor, - a classe
4D.WebSocketConnection
para gerir as ligações e as mensagens.
Além disso, terá de criar duas classes de utilizador que conterão funções de retorno de chamada:
- uma classe de usuário para tratar as ligações ao servidor,
- uma classe de usuário para tratar as mensagens.
Você deve criar o servidor WebSocket em um worker para manter a conexão ativa.
O 4D Web Server deve ser iniciado.
Exemplo
Neste exemplo básico, o nosso servidor WebSocket devolverá mensagens em maiúsculas.
- Crie o servidor WebSocket utilizando um trabalhador (obrigatório) e passe a sua classe de ligação ao servidor como parâmetro:
//criar uma instância da classe de usuário
//que manipulará as conexões com o servidor
var $handler:cs.myServerHandler
$handler:=cs.myServerHandler.new()
CALL WORKER("WebSocketServer"; Formula(wss:=4D.WebSocketServer.new($handler)))
//atribuir uma variável (wss) ao WebSocket permite que você
//chame wss.terminate() posteriormente
- Defina a classe de usuário
myServerHandler
que contém a(s) função(ões) de retorno de chamada usada(s) para tratar as conexões com o servidor:
//classe myServerHandler
Function onConnection($wss : Object; $event : Object) : Object
//retorna uma instância da classe de usuário
//que tratará as mensagens
return cs.myConnectionHandler.new()
- Defina a classe de usuário
myConnectionHandler
que contém a(s) função(ões) de retorno de chamada usada(s) para tratar mensagens:
// minhaConnectionHandler classe
Function onMessage($ws : 4D.WebSocketConnecation; $message : Object)
//reenvia a mensagem em maiúsculas
$ws.send(Uppercase($message.data))
Consulte esta publicação no blog para ver um exemplo de código Javascript do lado do cliente que manipula uma conexão WebSocket.
Objecto WebSocketServer
Os objectos de servidor WebSocket fornecem as seguintes propriedades e funções:
.connections : Collection todas as conexões atuais tratadas pelo servidor WebSocket |
.dataType : Text o tipo de dados recebidos ou enviados |
.handler : Object o acessório que obtém o objeto WSSHandler usado para iniciar o servidor WebSocket |
.path : Text o padrão do caminho para acessar o servidor de WebSocket |
.terminate() .terminate( timeout : Integer ) fecha o servidor de WebSocket |
.terminated : Boolean True se o servidor de WebSocket estiver fechado |
4D.WebSocketServer.new()
4D.WebSocketServer.new( WSSHandler : Object { ; options : Object } ) : 4D.WebSocketServer
Parâmetro | Tipo | Descrição | |
---|---|---|---|
WSSHandler | Object | -> | Objecto da classe de utilizador que declara as chamadas de retorno do servidor WebSocket |
options | Object | -> | Parâmetros de configuração do WebSocket |
Resultados | 4D.WebSocketServer | <- | Novo objeto WebSocketServer |
A função 4D.WebSocketServer.new()
cria e inicia um servidor WebSocket que usará os retornos de chamada especificados WSSHandler e (opcionalmente) opções e retorna um objeto 4D.WebSocketServer
.
A chamada dessa função requer que o 4D Web Server seja iniciado. O host e a port do servidor WebSocket são os mesmos que o host e a porta do 4D Web Server.
Parâmetro WSSHandler
No parâmetro WSSHandler, passe uma instância de uma classe de usuário que será chamada sempre que ocorrer um evento no servidor WebSocket - essencialmente, eventos de conexão. A classe deve definir as seguintes funções de retorno de chamada (somente onConnection
é obrigatório):
Propriedade | Tipo | Descrição | Por padrão |
---|---|---|---|
onConnection | Function | (obrigatório) Chamada de retorno quando é iniciada uma nova ligação de cliente (ver abaixo) | indefinido |
onOpen | Function | Callback quando o servidor WebSocket é iniciado (ver abaixo) | indefinido |
onTerminate | Function | Callback quando o servidor WebSocket é terminado (ver abaixo) | indefinido |
onError | Function | Callback quando ocorre um erro (ver abaixo) | indefinido |
WSHandler.onConnection(WSServer : Object ; event : Object) : Object | null
Parâmetro | Tipo | Descrição | ||
---|---|---|---|---|
WSServer | 4D.WebSocketServer | <- | Objecto actual do servidor WebSocket | |
"event" | Object | <- | Parâmetros | |
type | Text | "connection" | ||
request | Object | objeto request . Contém informações sobre o pedido de ligação (ver abaixo) | ||
Resultado | Object | -> | connectionHandler object (veja abaixo). Se essa função retornar um objeto connectionHandler , um objeto 4D.WebSocketConnection é criado automaticamente e adicionado à coleção de conexões. Esse objeto é então recebido como parâmetro em cada função do objeto connectionHandler . Se o valor devolvido for nulo ou indefinido, a ligação é cancelada. |
Esta chamada de retorno é feita quando o handshake estiver concluído. Ele deve ser chamado com um objeto connectionHandler
válido para criar a conexão WebSocket; caso contrário, a conexão será cancelada.
WSHandler.onOpen(WSServer : Object ; event : Object)
Parâmetro | Tipo | Descrição | ||
---|---|---|---|---|
WSServer | 4D.WebSocketServer | <- | Objecto actual do servidor WebSocket | |
"event" | Object | <- | Parâmetros | |
type | Text | "open" |
Evento emitido quando o servidor websocket é iniciado.
WSHandler.onTerminate(WSServer : Object ; event : Object)
Parâmetro | Tipo | Descrição | ||
---|---|---|---|---|
WSServer | 4D.WebSocketServer | <- | Objecto actual do servidor WebSocket | |
"event" | Object | <- | Parâmetros | |
type | Text | "terminate" |
Evento emitido quando o servidor HTTP ou o servidor WebSocket é encerrado.
WSHandler.onError(WSServer : Object ; event : Object)
Parâmetro | Tipo | Descrição | ||
---|---|---|---|---|
WSServer | 4D.WebSocketServer | <- | Objecto actual do servidor WebSocket | |
"event" | Object | <- | Parâmetros | |
type | Text | "error" | ||
errors | Collection | Coleção da pilha de erros 4D em caso de erro de execução |
Evento emitido quando ocorre um erro no servidor WebSocket.
Exemplo de classe WSSHandler
Este exemplo de um recurso básico de bate-papo ilustra como lidar com conexões de servidor WebSocket em uma classe WSSHandler.
//myWSServerHandler class
Function onConnection($wss : Object; $event : Object) : Object
If (VerifyAddress($event.request.remoteAddress))
// O método VerifyAddress valida o endereço do cliente
// O objeto WSConnectionHandler retornado será usado
// por 4D para instanciar o objeto 4D.WebSocketConnection
// relacionado a essa conexão
return cs.myConnectionHandler.new()
// Veja o objeto connectionHandler
Else
// A conexão é cancelada
return Null
End if
Function onOpen($wss : Object; $event : Object)
LogFile("*** Server started")
Function onTerminate($wss : Object; $event : Object)
LogFile("*** Server closed")
Function onError($wss : Object; $event : Object)
LogFile("!!! Erro do servidor: "+$event.errors.first().message)
objeto request
Um objeto request
contém as seguintes propriedades:
Parâmetro | Tipo | Descrição |
---|---|---|
headers | Object | O pedido HTTP GET do cliente. headers.key=value (o valor pode ser uma coleção se a mesma chave aparecer várias vezes) |
query | Object | Objecto que contém os parâmetros URL. Por exemplo, se os parâmetros são: ?key1=value1&key2=value2 -> query.key1=value1 , query.key2=value2 |
url | Text | contém apenas o URL que está presente no pedido HTTP efectivo. Ex: GET /status?name=ryan HTTP/1.1 -> url="/status?name=ryan" |
remoteAddress | Text | Endereço IP do cliente |
objeto connectionHandler
Como resultado do WSHandler. callback nConnection
, passe um objeto connectionHandler
, que é uma instância de uma classe de usuário que será chamada toda vez que um evento ocorrer na conexão de WebSocket --essencialmente, mensagens recebidas. A classe deve definir as seguintes funções de retorno de chamada (somente onConnection
é obrigatório):
Parâmetro | Tipo | Descrição |
---|---|---|
onMessage | Function | (obrigatório) Função chamada quando é recebida uma nova mensagem desta ligação |
onOpen | Function | Função chamada quando o 4D.WebSocketConnection é criado |
onTerminate | Function | Função chamada quando esta ligação é terminada |
onError | Function | Função chamada quando ocorre um erro |
connectionHandler.onMessage(ws : 4D.WebSocketConnection ; event : Object)
Parâmetro | Tipo | Descrição | ||
---|---|---|---|---|
ws | 4D.WebSocketConnection | <- | Objecto de ligação WebSocket actual | |
"event" | Object | <- | Parâmetros | |
type | Text | "message" | ||
data | Text / Blob / Object | dados enviados pelo cliente |
Este Callback para dados WebSocket. Chamado sempre que o WebSocket recebe dados.
connectionHandler.onOpen(ws : 4D.WebSocketConnection ; event : Object)
Parâmetro | Tipo | Descrição | ||
---|---|---|---|---|
ws | 4D.WebSocketConnection | <- | Objecto de ligação WebSocket actual | |
"event" | Object | <- | Parâmetros | |
type | Text | "open" |
Chamado quando o objeto connectionHandler
for criado (após o evento WSS.onConnection
).
connectionHandler.onTerminate(ws : 4D.WebSocketConnection ; event : Object)
Parâmetro | Tipo | Descrição | ||
---|---|---|---|---|
ws | 4D.WebSocketConnection | <- | Objecto de ligação WebSocket actual | |
"event" | Object | <- | Parâmetros | |
type | Text | "terminate" | ||
code | Number | Código de estado que indica o motivo pelo qual a ligação foi encerrada. Se o WebSocket não retorna um código de erro, code está definido para 1005 se nenhum erro ocorreu ou para 1006 se houve um erro. | ||
reason | Text | Cadeia de caracteres que explica porque é que a ligação foi encerrada. Se o websocket não devolver um motivo, o código é indefinido |
Função chamada quando o WebSocket é fechado.
connectionHandler.onError(ws : 4D.WebSocketConnection ; event : Object)
Parâmetro | Tipo | Descrição | |||
---|---|---|---|---|---|
ws | 4D.WebSocketConnection | <- | Objecto de ligação WebSocket actual | ||
"event" | Object | <- | Parâmetros | ||
type | Text | "error" | |||
errors | Collection | Coleção de erros 4D stack em caso de erro de execução |
Função chamada quando ocorre um erro.
Exemplo de classe connectionHandler
Este exemplo de um recurso básico de bate-papo ilustra como tratar mensagens em uma classe connectionHandler.
// myConnectionHandler Class
Function onMessage($ws : 4D.WebSocketConnection; $message : Object)
// Reenvia a mensagem a todos os clientes de chat
This.broadcast($ws;$message.data)
Function onOpen($ws : 4D.WebSocketConnection; $message : Object)
// Envia uma mensagem aos novos usuários conectados
$ws.send("Welcome on the chat!")
// Envia a mensagem "Novo cliente conectado" a todos os outros clientes de chat
This.broadcast($ws; "New client connected")
Function onTerminate($ws : 4D.WebSocketConnection; $message : Object)
// Envia a mensagem "Client disconnected" a todos os outros clientes de bate-papo
This.broadcast($ws; "Client disconnected")
Function broadcast($ws : 4D.WebSocketConnection; $message:text)
var $client:4D.WebSocketConnection
// Reenviar a mensagem a todos os clientes de bate-papo
For each ($client; $ws.wss.connections)
// Verificar se o id não é a conexão atual
If ($client.id#$ws.id)
$client.send($message)
End if
End for each
Parâmetro options
No parâmetro opcional options, passe um objeto que contenha as seguintes propriedades:
Propriedade | Tipo | Descrição | Por padrão |
---|---|---|---|
path | Text | Representa o caminho para aceder ao servidor WebSocket. Se não for definido um caminho, o servidor WebSocket gere todas as ligações | indefinido |
dataType | Text | Tipo dos dados recebidos através da função connectionHandler.onMessage e os dados enviados por WebSocketConnection.send() . Values: "text", "blob","object"). Se "object": (enviar) transforma o objecto num formato json e envia-o; (recepção): recebe o formato json e transforma-o em objecto | text |
.connections
.connections : Collection
Descrição
A propriedade .connections
contém todas as conexões atuais tratadas pelo servidor WebSocket. Cada elemento da coleção é um objeto WebSocketConnection
.
Quando uma conexão é encerrada, seu status
muda para "Fechado" e ele é removido desta coleção.
.dataType
.dataType : Text
Descrição
A propriedade .dataType
contém o tipo de dados recebidos ou enviados.
Esta propriedade é só de leitura.
.handler
.handler : Object
Descrição
A propriedade .handler
contém o acessório que obtém o objeto WSSHandler
usado para iniciar o servidor WebSocket.
.path
.path : Text
Descrição
A propriedade .path
contém o padrão do caminho para acessar o servidor de WebSocket . Se não for definido um caminho, o servidor WebSocket gere todas as ligações.
Esta propriedade é só de leitura.
.terminate()
.terminate()
.terminate( timeout : Integer )
Parâmetro | Tipo | Descrição | |
---|---|---|---|
timeout | Integer | -> | Tempo de espera em segundos antes de terminar o servidor WebSocket |
Descrição
A função .terminate()
fecha o servidor de WebSocket.
Por padrão, se nenhum valor de timeout for definido, a função inicializa o handshake de fechamento e aguarda o recebimento do quadro de fechamento do par, após o que envia o pacote FIN para tentar fechar o soquete de forma limpa. Quando a resposta é recebida, o soquete é destruído.
Se um valor timeout for definido:
- quando o tempo de espera é alcançado, a força destrói o meio.
- se timeout = 0, forçando a destruir o soquete sem fechar quadros ou trocar pacotes finos, e instantaneamente sem tempo de espera.
.terminated
.terminated : Boolean
Descrição
A propriedade .terminated
contém True se o servidor de WebSocket estiver fechado.
Esta propriedade é só de leitura.