Novo Servidor Websocket Incorporado

Num mundo cada vez mais conectado, os websites ou aplicações da Internet de alta velocidade devem ser atualizados em tempo real.

Uma forma de fornecer informação instantaneamente aos seus sites é utilizar o protocolo Websocket que fornece um canal de comunicação full-duplex entre um servidor e um cliente. A partir do v20, 4D fornece comandos para criar um servidor Websocket.

Comandos para Criar um Servidor Websocket

Para gerir o seu servidor websocket, 4D fornece 2 novas classes:

  • A primeira gere o próprio servidor, 4D.WebSocketServer
  • A segunda gere as ligações do websocket: 4D.WebSocketConnection

 

Para demonstrar esta funcionalidade, vamos criar um servidor de chat simples!

Antes de utilizar a classe de servidor websocket, o seu servidor web 4D deve ser iniciado!

Servidor web 4D.WebSocketSocket

Esta classe permite-lhe gerir diferentes eventos que ocorrem no seu servidor. Para fazer isso, precisa criar uma classe com as funções abaixo:

  • onConnection(), chamada quando é solicitada uma nova ligação.
  • onOpen(), chamada quando o servidor for iniciado
  • onTerminate(), chamada quando o servidor para
  • onError(), chamada quando ocorrer um erro.

No nosso exemplo, precisamos primeiro gerir o pedido de ligação. Com a função onConnection(), pode cancelar uma ligação devolvendo Null ou um objecto que será utilizado para gerir a mensagem enviada ou recebida. No exemplo abaixo, devolvemos a classe WSConnectionHandler (descrita na seção seguinte):

Função onConnection($wss : Objecto; $param : Objecto) : Object
 // chamar o método VerifyAddress para verificar se o endereço remoto permite a ligação
If (VerifyAddress($param.request.remoteAddress))
// A ligação é permitida
// O objeto WSConnectionHandler devolvido é utilizado 
// por 4D para instanciar o 4D.O objecto WebSocketConnection
// relacionado com esta ligação
devolver cs.WSConnectionHandler.new() 
Else 
// A ligação é cancelada
devolver Null 
Terminar se 

Agora, queremos registar o início, fechar e erros, por isso criamos uma classe WSServerHandler:

Construtor da classe

Função onOpen($wss : Object; $param : Object)
LogFile("*** Servidor iniciado")

Função onTerminate($wss : Object; $param : Object)
LogFile("*** Servidor fechado")

Função onError($wss : Object; $param : Object)
LogFile("!!! Erro do servidor: "+$param.statusText)

4D.WebSocketConnection

Esta classe permite-lhe gerir diferentes eventos durante uma determinada ligação. Para o fazer, é necessário criar uma classe com as funções abaixo:

  • onMessage(), chamada cada vez que uma mensagem chega através desta ligação.
  • onOpen(), chamada quando o objeto 4D.WebSocketConnection é criado
  • onTerminate(), chamada quando o objeto 4D.WebSocketConnection é terminado
  • onError(), chamada quando ocorreu um erro

 

Para fazer o nosso chat, esta classe será a classe WSConnectionHandler. É ela:

  • avisa os outros utilizadores que um novo usuário está ligado quando a ligação for aberta
  • avisa os outros utilizadores que um utilizador é desligado quando a ligação for terminada
  • transmitir as mensagens recebidas a todos os outros clientes de chat ligados quando uma mensagem for recebida.

 

Função onMessage($ws : 4D.WebSocketConnection; $message : Object)
// reenviar a mensagem a todos os clientes do chat
This.broadcast($ws;$message.data)

Função onOpen($ws : 4D.WebSocketConnection; $message : Object)
// Enviar uma mensagem ao novo utilizador conectado 
$ws.send("Bem-vindo ao chat!")
// Enviar mensagem "Novo cliente conectado" a todos os outros clientes de chat
This.broadcast($ws; "Novo cliente conectado")

Função onTerminate($ws : 4D .WebSocketConnection; $message : Object)
// Enviar mensagem "Cliente desligado" a todos os outros clientes de chat
This.broadcast($ws; "Cliente desligado")

Função broadcast($ws : 4D.WebSocketConnection; $message : Text)
var $client:4D .WebSocketConnection
// reenviar a mensagem a todos os clientes de chat
Para cada ($client; $ws.wss.connections)
// Verificar se o id não é a ligação actual
If ($client.id#$ws.id)
$client.send($message)
Terminar se 
Terminar para cada 

Resta apenas iniciar o servidor websocket utilizando as classes criadas acima. Deve-se criar um novo processo com o comando CALL WORKER e instanciar nele o servidor 4D.WebSocketServer:

var $handler:cs.WSSHandler
$handler:=cs.WSServerHandler.new()

CALL WORKER("WebSocketServer"; Fórmula(WSS:=4D.WebSocketServer.new($handler))
//Atribuir uma variável (WSS) ao WebSocket permite-lhe chamar WSS.terminate() posteriormente

O servidor websocket criado existirá até que o trabalhador seja morto ou a função .terminate() seja chamada.

CALL WORKER("WebSocketServer"; Formula(WSS.terminate()))

Lado do cliente

Pode encontrar abaixo um exemplo de código em HTML e Javascript para criar uma interface de chat:

Este código foi concebido para funcionar com um servidor web local na porta HTTP 80 (linha 18: const urlwss=”ws://127.0.0.1:80/”;).

Verifique esta funcionalidade com o HDI acima e a documentação para mais detalhes!

Fabrice Mainguené
- Proprietário do produto ->p>Fabrice Mainguené juntou-se à equipa do Programa 4D em Novembro, 2016. Como Proprietário do Produto, está encarregado de escrever as histórias dos utilizadores, traduzindo-as depois para especificações funcionais. O seu papel é também o de assegurar que a implementação da funcionalidade entregue vai ao encontro das necessidades do cliente.Após a obtenção da licenciatura em Informática no CNAM, Fabrice juntou-se a uma pequena empresa editora de software como programador Windev. Depois trabalhou para diferentes empresas nas áreas da indústria e comércio como programador Windev e web developer, bem como como consultor técnico sobre novas funcionalidades.