メッセンジャー
メッセンジャーには、主に以下の機能があります。
- スケジューラーを起動している者同士で、簡単なメッセージのやり取りをリアルタイムに行える。
- 相手が不在の時にメッセージをデータベースに残すことができる。不在の人がスケジューラーを起動した際に、メッセージがあることを通知して後からメッセージを見ることができる。
UDPソケットの生成
UDPで送受信を行うときは、UDPパケットの送受信のためのクラスであるUDPSocketを使います。引数で使用するポート番号、タイムアウト時間、データを受信した時に呼ばれるイベントハンドラを指定します。bindメソッドを実行すると送受信できる状態になります。
let v_socket: UDPSocket= {UDPSocket local-port = 5000, timeout = Socket.zero-timeout, readable-handler = {on t: ReadableStreamEvent do ||データを受信したときに呼ばれる {recv-data-proc} } } {v_socket.bind}
UDPで文字列を送信
文字列を送信するには、UDPSocketクラスのwrite-packetメソッドを使用します。write-packetメソッドで送信できるデータ形式はバイト配列です。よって、送信する前に文字列をencode-charactersプロシージャでバイト配列に変換しています。
{define-proc {my-udp-send-string? p_socket: #UDPSocket, p_ip: String, p_port: uint16, p_data: String }: bool {if p_socket == null or not p_socket.open? then {return false} } let v_enc: CharEncoding = {get-character-encoding-by-name "shift-jis"}, v_outsize: int = p_data.size * v_enc.transcode-max-expansion-factor, v_out: ByteVec = {ByteVec max-size = v_outsize}, (v_used: int, v_outmade: int) = {encode-characters p_data, v_out, v_enc}, v_temp: {Array-of byte} = {new {Array-of byte}} {for v_byte: byte in v_out do {v_temp.append v_byte} } {return {p_socket.write-packet v_temp, remote-address = {SocketInetAddress p_ip}, remote-port = p_port } } } ||192.168.1.123に"あいうえお"を送信する {my-udp-send-string? v_socket, "192.168.1.123", 5000, "あいうえ" }
UDPで送信された文字列の受信
データを受信するときは、UDPSocketクラスを生成するときのreadable-handlerに指定したイベントハンドラで行います。 UDPSocketクラスのread-packetメソッドで、受信したデータを取得します。バイト配列で取得するので、decode- charactersプロシージャを使ってバイト配列から文字列に変換しています。
{define-proc {recv-data-proc}: void {try let (v_out: #{Array-of byte}, v_length: int, v_remote-address: #SocketInetAddress, v_remote-port: uint16) = {v_socket.read-packet} {if-non-null v_out then let v_temp: ByteVec = {ByteVec max-size = v_out.size} {for v_byte: byte in v_out do {v_temp.append v_byte} } let (v_num-bytes-decoded: int, v_recv: String) = {decode-characters v_temp, {get-character-encoding-by-name "shift-jis"} } : 省 略 : } catch e: ConnectionAbortedSocketException do } }
メッセンジャーの機能を応用して、グループメンバのスケジューラーの起動の有無を名前の前のアイコンで分かるようにしました。スケジューラーを起動すると、グループメンバのスケジューラーとメッセージの送受信を開始します。応答がある/なしによってアイコンの切り替えを行っています。
まとめ
Curlで、デスクトップアプリケーションのようなRSSリーダー・メッセンジャーが簡単に作成できることがお分かりいただけたと思います。
3回にわたり、Curlで「ポータル・スケジューラー」を開発するにあたり苦労した点、工夫した点などを書いてきました。本連載で少しでもCurlの良さを伝えることができたならば幸いです。ありがとうございました。