メッセンジャー
メッセンジャーには、主に以下の機能があります。
- スケジューラーを起動している者同士で、簡単なメッセージのやり取りをリアルタイムに行える。
- 相手が不在の時にメッセージをデータベースに残すことができる。不在の人がスケジューラーを起動した際に、メッセージがあることを通知して後からメッセージを見ることができる。


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の良さを伝えることができたならば幸いです。ありがとうございました。


