En un mundo cada vez más conectado, los sitios web o las aplicaciones IoT deben actualizarse en tiempo real.
Una forma de entregar información instantáneamente a sus sitios es utilizar el protocolo Websocket que ofrece un canal de comunicación full-duplex entre un servidor y un cliente. Desde la v20, 4D ofrece comandos para crear un servidor Websocket.
Comandos para crear un servidor Websocket
Para gestionar su servidor websocket, 4D ofrece dos nuevas clases:
- La primera gestiona el propio servidor, 4D.WebSocketServer
- La segunda gestiona las conexiones websocket: 4D.WebSocketConnection
Para demostrar esta funcionalidad, vamos a crear un simple servidor de chat.
Antes de usar la clase servidor websocket, ¡Su servidor web 4D debe estar iniciado!
4D.WebSocketServer
Esta clase le permite manejar diferentes eventos que ocurren en su servidor. Para ello, necesita crear una clase con las siguientes funciones:
- onConnection(), llamada cuando se solicita una nueva conexión.
- onOpen(), llamada cuando se inicia el servidor
- onTerminate(), llamada cuando el servidor se detiene
- onError(), llamada cuando se produce un error.
En nuestro ejemplo, primero tenemos que gestionar la solicitud de conexión. Con la función onConnection(), puede cancelar una conexión devolviendo Null o un objeto que se utilizará para gestionar el mensaje enviado o recibido. En el siguiente ejemplo, devolvemos la clase WSConnectionHandler (descrita en la siguiente sección):
Function onConnection($wss : Objeto; $param : Objeto) : Object
// llamar al método VerifyAddress para verificar si la dirección remota permite la conexión
If (VerifyAddress($param.request.remoteAddress))
// La conexión es permitida
// El objeto WSConnectionHandler devuelto es utilizado
// por 4D para instanciar el objeto 4D.WebSocketConnection
// relacionado con esta conexión
return cs.WSConnectionHandler.new()
Else
// La conexión se cancela
return Null
End if
Ahora, queremos registrar el inicio, cierre y errores, así que creamos una clase WSServerHandler:
Constructor de la clase
Function onOpen($wss : Object; $param : Object)
LogFile("*** Servidor iniciado")
Function onTerminate($wss : Object; $param : Object)
LogFile("*** Servidor cerrado")
Function onError($wss : Object; $param : Object)
LogFile("!!! Error de servidor: "+$param.statusText)
4D.WebSocketConnection
Esta clase permite gestionar diferentes eventos durante una determinada conexión. Para ello, es necesario crear una clase con las siguientes funciones:
- onMessage(), llamada cada vez que llega un mensaje a través de esta conexión.
- onOpen(), llamada cuando se crea el objeto 4D.WebSocketConnection
- onTerminate(), llamada cuando se termina el objeto 4D.WebSocketConnection
- onError(), llamada cuando se produce un error
Para hacer nuestro chat, esta clase será la clase WSConnectionHandler. Esta clase
- avisa a otros usuarios de que un nuevo usuario está conectado cuando se abre la conexión
- avisa a los demás usuarios de que un usuario se ha desconectado cuando se termina la conexión
- difunde los mensajes recibidos a todos los demás clientes de chat conectados cuando se recibe un mensaje.
Function onMessage($ws : 4D.WebSocketConnection; $message : Object)
// reenviar el mensaje a todos los clientes de chat
This.broadcast($ws;$message.data)
Function onOpen($ws : 4D.WebSocketConnection; $message : Object)
// Enviar un mensaje al nuevo usuario conectado
$ws.send("¡Bienvenido al chat!")
// Enviar el mensaje "Nuevo cliente conectado" a todos los demás clientes del chat
This.broadcast($ws; "Nuevo cliente conectado")
Function onTerminate($ws : 4D.WebSocketConnection; $message : Object)
// Enviar mensaje "Cliente desconectado" a todos los demás clientes del chat
This.broadcast($ws; "Cliente desconectado")
Function broadcast($ws : 4D.WebSocketConnection; $message : Text)
var $client:4D.WebSocketConnection
// reenviar el mensaje a todos los clientes del chat
For each ($client; $ws.wss.connections)
// Verificar que el id no es la conexión actual
If ($client.id#$ws.id)
$client.send($message)
End if
End for each
Todo lo que queda es iniciar el servidor websocket usando las clases creadas anteriormente. Un servidor websocket debe iniciarse en un worker, así que creamos un nuevo proceso con el comando CALL WORKER e instanciamos el 4D.WebSocketServer en él:
var $handler:cs.WSSHandler
$handler:=cs.WSServerHandler.new()
CALL WORKER("WebSocketServer"; Formula(WSS:=4D.WebSocketServer.new($handler)))
//Asignar una variable (WSS) al WebSocket permite llamar después a WSS.terminate()
El servidor websocket creado existirá hasta que el trabajador sea eliminado o se llame a la función .terminate().
CALL WORKER("WebSocketServer"; Formula(WSS.terminate()))
Del lado del cliente
A continuación puede encontrar un ejemplo de código en HTML y Javascript para crear una interfaz de chat:
Este código está diseñado para funcionar con un servidor web local en el puerto HTTP 80 (línea 18: const urlwss=»ws://127.0.0.1:80/»;).
Consulte esta función con el IDH anterior y la documentación para obtener más detalles.