4D 20 R8 では TCPConnectionクラスが導入され、TCPクライアント接続をオブジェクト指向で非同期に処理できるようになりました。そして 4D 20 R9 では、TCPサーバーを構築するための TCPListenerクラスが登場しました。そして今、4D 20 R10 では、新しい UDPSocketクラス が完成したことで、あらゆるリモートマシンとの UDP通信を、クライアントとして、あるいはサーバーとして管理できるようになりました。これは特に IoT、リアルタイムモニタリング、ブロードキャスト通信に便利です。そしてなにより、このクラスは、プリエンプティブおよび非同期なUDP通信をサポートします。
最後に、この新機能は廃止予定である Internet Commands プラグインを置き換える最終ステップとなります。
それでは詳細を説明しましょう。
なぜ UDP なのか?
UDP は軽量でコネクションレスのプロトコルです。TCP とは異なり、2つのエンドポイント間の持続的な接続を維持しません。確認や再送のメカニズムが組み込まれていないため、IoT、リアルタイムモニタリング、ブロードキャストなどのサードパーティーによって課される「送りっぱなし」のシナリオに便利です。
新しい UDPSocketクラスにより、4D で UDPパケットの送受信を完全にコントロールできるようになりました。以下に示す原則は、こちらの HDI でも説明されています:
UDPクライアントクラスの定義
UDPサーバーへのデータ送信を行う単純な clientUDP クラスの例です:
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
// UDPサーバーにメッセージを送信します
Function sendMessage($message : Text)
var $blob : Blob
TEXT TO BLOB($message; $blob; UTF8 text without length)
This.socket.send($blob; This.ip; This.port)
// ソケットが想定外に閉じられたときに呼び出されるコールバック
Function onError($socket : 4D.UDPSocket; $event : 4D.UDPEvent)
ALERT("clientUDP インスタンスエラー")
// ソケットが閉じられたか、エラーが発生した場合にトリガーされるコールバック
Function onTerminate($socket : 4D.UDPSocket; $event : 4D.UDPEvent)
ALERT("clientUDP インスタンス終了")
この例では:
- コンストラクターはターゲットIP とポートを設定します。
- sendMessage関数は、引数として渡されたメッセージを送信します。
- onError と onTerminate はライフサイクルイベントを処理します。
- UDPクライアントは通常レスポンスを受け取らないため、onData は必要ありません。
UDPサーバークラスの定義
では、UDPメッセージの着信をリッスンする serverUDP クラスを見てみましょう:
property socket : 4D.UDPSocket
// コンストラクターは、引数で指定されたポートをリッスンする UDPSocket を作成します
Class constructor($port : Integer)
This.socket:=4D.UDPSocket.new($port; This)
// データ受信時に呼び出されるコールバック
Function onData($socket : 4D.UDPSocket; $event : 4D.UDPEvent)
var $data:=BLOB to text($event.data; UTF8 text without length)
ALERT("serverUDP インスタンス: 受信メッセージ:\r\n"+$data)
// 接続が想定外に閉じられたときに呼び出されるコールバック
Function onError($socket : 4D.UDPSocket; $event : 4D.UDPEvent)
ALERT("serverUDP インスタンス: エラー\r\n"+JSON Stringify($event.data; *))
// ソケットが閉じられたか、エラーが発生した場合にトリガーされるコールバック
Function onTerminate($socket : 4D.UDPSocket; $event : 4D.UDPEvent)
ALERT("serverUDP インスタンス: サーバー終了")
ここでは:
- サーバーは、コンストラクターに引数として渡されたポートをリッスンします。
- onData コールバックは、受信メッセージを処理します。新しい UDPEvent クラスのインスタンスにメッセージは格納されます。
- クライアントと同様に、onError と onTerminate がライフサイクルイベントを管理します。
Worker でのサーバーを実行する
サーバーを独立して実行し続けるには、ワーカーで起動する必要があります:
CALL WORKER("myServerUDP"; Formula(cs.serverUDP.new(12345)))
注意: UDPソケットは、オブジェクトへの参照がなくなると自動的に解放されます。この場合、ワーカーを終了するとサーバーも終了します。
クライアントからサーバーへデータを送信する
両方のクラスが設置されると、メッセージの送信は次のように簡単になります:
cs.clientUDP.new("127.0.0.1"; 12345).sendMessage("テストメッセージ")
4D では、UDP通信がかつてないほど簡単になりました。新しい UDPSocket クラスにより、デバイスへのコマンド送信や、リモートシステムの報告をリッスンするなど、軽量でリアルタイムな通信機能をアプリケーションに組み込むことができます。
この新機能が、あなたのプロジェクトにエキサイティングな可能性を開くことを願っています。
ついに、Internet Commands プラグインを取り除く時が来ました!
ハッピー・コーディング!
