WebSocketServer
A classe WebSocketServer
permite-lhe criar e configurar um servidor WebSocket em 4D. Uma vez que o servidor 4D WebSocket está ativo, você pode abrir e usar conexões WebSocket entre 4D e clientes usando a classe WebSocketConnection
.
Histórico
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 mais informações sobre servidores WebSocket, leia esta página na Wikipédia.
Veja também este post do blog sobre o servidor 4D WebSocket.
Requisitos
Para criar e manipular seu servidor WebSocket em 4D, é preciso usar duas classes embutidas em 4D:
- esta classe (
4D.WebSocketServer
) para gerir 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.
É necessário criar o servidor WebSocket dentro de um worker para manter a ligação activa.
O servidor 4D Web 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 utilizador
//que tratará das ligações ao 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-lhe
//chamar posteriormente wss.terminate()
- Definir a classe de utilizador
myServerHandler
que contém as funções de retorno de chamada utilizadas para tratar as ligações ao servidor:
//classe myServerHandler
Function onConnection($wss : Object; $event : Object) : Object
//retorna uma instância da classe de utilizador
//que tratará as mensagens
return cs.myConnectionHandler.new()
- Definir a classe de utilizador
myConnectionHandler
que contém funções de retorno de chamada utilizadas para tratar mensagens:
// myConnectionHandler class
Function onMessage($ws : 4D.WebSocketConnection; $message : Object)
//resends the message in uppercase
$ws.send(Uppercase($message.data))
Consulte esta publicação do blogue para obter um exemplo de código Javascript do lado do cliente que trata de uma ligação WebSocket.
Objecto WebSocketServer
Os objectos de servidor WebSocket fornecem as seguintes propriedades e funções:
.connections : Collection todas as ligações actuais tratadas pelo servidor WebSocket |
.dataType : Text o tipo de dados recebidos ou enviados |
.handler : Objecto o acessor que obtém o objecto WSSHandler utilizado para iniciar o servidor WebSocket |
.path : Text o padrão do caminho para aceder ao servidor WebSocket |
.terminate() .terminate( timeout : Integer ) fecha o servidor WebSocket |
.terminated : Boolean True se o servidor 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 utilizará as chamadas de retorno WSSHandler e (opcionalmente) as opções especificadas, e devolve um objecto 4D.WebSocketServer
.
Para chamar esta função é necessário que o servidor Web 4D seja iniciado. O host **** e a porta **** do servidor WebSocket são os mesmos que o host e a porta do Servidor Web 4D.
ParâmetroWSSHandler
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 (apenas 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 | objecto request . Contém informações sobre o pedido de ligação (ver abaixo) | ||
Resultado | Object | -> | objecto connectionHandler (ver abaixo). Se esta função devolver um objecto connectionHandler , um objecto 4D.WebSocketConnection é automaticamente criado e adicionado à colecção de ligações. Este objecto é então recebido como parâmetro em cada função do objecto connectionHandler . Se o valor devolvido for nulo ou indefinido, a ligação é cancelada. |
Esta chamada de retorno é feita quando o handshake estiver concluído. Deve ser chamada com um objecto connectionHandler
válido para criar a ligação WebSocket, caso contrário a ligação é 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 | Recolha da pilha de erros 4D em caso de erro de execução |
Evento emitido quando ocorre um erro no servidor WebSocket.
Exemplo de class 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))
// The VerifyAddress method validates the client address
// The returned WSConnectionHandler object will be used
// by 4D to instantiate the 4D.WebSocketConnection object
// related to this connection
return cs.myConnectionHandler.new()
// See connectionHandler object
Else
// The connection is cancelled
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)
request
object
Um pedido O objecto
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 forem: ?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 |
Objecto connectionHandler
Como resultado da chamada de retorno WSHandler.onConnection
, passe um objeto connectionHandler
, que é uma instância de uma classe de usuário que será chamada sempre que ocorrer um evento na conexão WebSocket -- essencialmente, mensagens recebidas. A classe deve definir as seguintes funções de retorno de chamada (apenas onMessage
é 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 a 4D.WebSocketConnection é criada |
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 objecto connectionHandler
é 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 devolver um código de erro, o código `` é definido como 1005 se não tiver ocorrido qualquer erro ou como 1006 se tiver ocorrido 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 | Pilha de erros 4D em caso de erro de execução |
Função chamada quando ocorre um erro.
Exemplo de class connectionHandler
Este exemplo de uma funcionalidade básica de conversação ilustra como tratar mensagens numa classe connectionHandler .
// myConnectionHandler Class
Function onMessage($ws : 4D.WebSocketConnection; $message : Object)
// Resend the message to all chat clients
This.broadcast($ws;$message.data)
Function onOpen($ws : 4D.WebSocketConnection; $message : Object)
// Send a message to new connected users
$ws.send("Welcome on the chat!")
// Send "New client connected" message to all other chat clients
This.broadcast($ws;"New client connected")
Function onTerminate($ws : 4D.WebSocketConnection; $message : Object)
// Send "Client disconnected" message to all other chat clients
This.broadcast($ws;"Client disconnected")
Function broadcast($ws : 4D.WebSocketConnection; $message:text)
var $client:4D.WebSocketConnection
// Resend the message to all chat clients
For each ($client; $ws.wss.connections)
// Check that the id is not the current connection
If ($client.id#$ws.id)
$client.send($message)
End if
End for each
Parâmetro options
No parâmetro opcional options , passe um objecto 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 dos dados enviados pela função 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 ligações actuais tratadas pelo servidor WebSocket. Cada elemento da colecção é um objecto WebSocketConnection
.
Quando uma ligação é terminada, o seu estado `` muda para "Fechado" e é removido desta colecçã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 : Objecto
Descrição
The .handler
property contains o acessor que obtém o objecto WSSHandler
utilizado para iniciar o servidor WebSocket.
.path
.path : Text
Descrição
A propriedade .path
contém o padrão do caminho para aceder ao servidor 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 | -> | Waiting time in seconds before terminating the WebSocket server |
Descrição
A função .terminate()
fecha o servidor WebSocket.
By default, if no timeout value is set, the function initializes close handshake and waits to receive close frame from the peer, after that sending FIN packet in attempt to perform a clean socket close. When answer received, the socket is destroyed.
If a timeout value is set:
- when the waiting time is reached, forcibly destroys the socket.
- if timeout = 0, forcibly destroys the socket without closing frames or fin packets exchange, and does it instantly without waiting time.
.terminated
.terminated : Boolean
Descrição
A propriedade .terminated
contém True se o servidor WebSocket estiver fechado.
Esta propriedade é só de leitura.