Nova classe para executar comunicações UDP

Tradução automática de Deepl

4D 20 R8 introduziu a classe TCPConnection, trazendo uma forma assíncrona e orientada a objetos para lidar com conexões de clientes TCP. Depois veio 4D 20 R9 com a classe TCPListener para construir servidores TCP. E agora, com 4D 20 R10, estamos completando o quadro com a nova classe UDPSocket, permitindo gerenciar comunicações UDP entre 4D e qualquer máquina remota, tanto como cliente quanto como servidor. Isso é especialmente útil para IoT, monitoramento em tempo real, ou trocas de transmissão. E a cereja do bolo? Essa classe suporta comunicação UDP preemptiva e assíncrona
Por fim, esse novo recurso está marcando a etapa final na substituição do plug-in de comandos da Internet herdado.
Vamos mergulhar nos detalhes.

Por que UDP?

O UDP é um protocolo leve e sem conexão. Ao contrário do TCP, ele não mantém uma conexão persistente entre os dois pontos de extremidade. Não há mecanismo de reconhecimento ou retransmissão embutido, tornando-o útil para cenários de “enviar e esquecer” impostos por terceiros, como IoT, monitoramento em tempo real ou transmissão.
Com a nova classe UDPSocket, agora tem controlo total sobre o envio e receção de pacotes UDP em 4D. Os princípios apresentados abaixo também são descritos nesse HDI:

HDI UDPSocket

Definindo uma classe cliente UDP

Aqui está uma classe clienteUDP simples que lida com o envio de dados para um servidor UDP:

property socket : 4D.UDPSocket
property ip : Text
property port : Integer

Class constructor ($ip: Text; $port: Integer)
This .socket:=4D.UDPSocket.new(0; This)
This .ip:=$ip
This .port:=$port

//Send message to the UDP server
Function sendMessage ($message: Text)

var $blob : Blob
TEXT TO BLOB ($message; $blob; UTF8 text without length)
This .socket.send($blob; This.ip; This.port)

//Callback called when the socket is closed unexpectedly
Function onError ($socket: 4D.UDPSocket; $event: 4D.UDPEvent)

ALERT ("clientUDP instance error")

//Callback called after onShutdown/onError just before the UDPSocket object is released
Function onTerminate($socket : 4D.UDPSocket; $event : 4D.UDPEvent)

ALERT ("clientUDP instance termination")

Neste exemplo:

  • O construtor define o IP e a porta de destino.
  • A função switch envia uma mensagem simples “switch”.
  • onError e onTerminate tratam dos eventos do ciclo de vida.
  • Não é necessário onData – os clientesUDP normalmente não recebem respostas.

 

Definindo uma classe de servidor UDP

Agora vamos dar uma olhada em uma classe serverUDP que escuta as mensagens UDP que chegam:

property socket : 4D.UDPSocket

//The constructor creates a UDPSocket to listen to the port given in parameter
Class constructor ($port: Integer)

This .socket:=4D.UDPSocket.new($port; This)

//Callback called when receiving data
Function onData ($socket: 4D.UDPSocket; $event: 4D.UDPEvent)

var $data :=BLOB to text($event.data; UTF8 text without length)

ALERT ("serverUDP instance: Received message:\r\n "+$data)

//Callback called when the connection is closed unexpectedly
Function onError ($socket: 4D.UDPSocket; $event: 4D.UDPEvent)

ALERT ("serverUDP instance: error\r\n "+JSON Stringify($event.data; *))

//Callback called after onShutdown/onError just before the UDPSocket object is released
Function onTerminate ($socket: 4D.UDPSocket; $event: 4D.UDPEvent)

ALERT ("serverUDP instance: Server termination")

Aqui:

  • O servidor escuta na porta dada como parâmetro do construtor.
  • A chamada de retorno onData trata das mensagens recebidas. As mensagens são armazenadas numa instância da nova classe UDPEvent.
  • Tal como acontece com o cliente, onError e onTerminate gerem eventos do ciclo de vida.

 

Executando o servidor em um trabalhador

Para manter o servidor a funcionar de forma independente, tem de o lançar num trabalhador:

CALL WORKER("myServerUDP"; Formula(cs.serverUDP.new(12345)))

Nota: O soquete UDP é liberado automaticamente quando não há mais referência no objeto. Nesse caso, a interrupção do worker encerrará o servidor.

Enviando dados do cliente para o servidor

Uma vez que ambas as classes estejam no lugar, enviar uma mensagem é tão simples quanto:

cs.clientUDP.new("127.0.0.1"; 12345).sendMessage("Mensagem de teste")
A comunicação UDP nunca foi tão fácil em 4D. Com a nova classe UDPSocket, agora pode construir caraterísticas de comunicação leves e em tempo real em suas aplicações – quer esteja enviando comandos a um dispositivo ou escutando atualizações de um sistema remoto.
Esperamos que este novo recurso abra possibilidades interessantes para seus projetos.
É hora de se livrar do plug-in Comandos da Internet!
Boa programação!

Avatar
• Proprietário do produto - Damien Fuzeau entrou ao time 4D Product em fevereiro de 2019. Como Proprietário do Produto, está a cargo de escrever as histórias dos usuários e depois traduzi-las em especificações funcionais. Seu papel também é garantir que a implementação da funcionalidade entregue cumpra com as necessidades do cliente. Damien é formado em engenharia de software pela Universidade de Nantes. Trabalhou mais de 23 anos em sua empresa anterior, primeiro como desenvolvedor (descobrindo 4D em 1997), e mais tarde como gerente de engenharia e arquiteto de software. Essa empresa é um Partner OEM de 4D e lançou softwares empresariais baseados em 4D para milhares de usuários em centenas de servidores. Portanto Damien está acostumado ao desenvolvimento e lançamento de 4D em contextos multilinguais.