💎
それ、F#でやってみました - WebSocket (サーバ:Bun 1.1 + クライアント:.NET ClientWebSocket)
.NETのClientWebSocketクラスを使ってF#で文字列を送受信するWebSocketクライアントを作成してみました。WebSocketのサーバは受信した文字列をそのまま送信(エコー)するものをBun1.1で作成しました。
サーバ:ASP.NET Core + クライアント:Bun 1.1はこちら
WebSocketクライアント(Program.fs)
// .NET での WebSocket のサポート
// https://learn.microsoft.com/ja-jp/dotnet/fundamentals/networking/websockets
// WebSocketクライアント サーバに文字列を送信、受信した文字列を表示
// クライアントから先に切断すること
// .NET 9 Preview 3 対応
// dotnet new console -lang f# -o ディレクトリ名
// cd ディレクトリ名
// (Program.fsを編集)
// dotnet run
open System
open System.Net.WebSockets
open System.Text
open System.Threading
// メイン(エントリーポイント)
[<EntryPoint>]
let main args =
// メッセージ入力時のプロンプト
let prompt = "ws> "
// 受信用バッファ
let bytes = Array.zeroCreate<byte> 1024
// メッセージ入力を継続するか
let mutable cond = true;
// 受信メッセージ用
let mutable message = ""
// WebSocketの接続先
let uri = Uri "ws://localhost:5080/ws"
// クライアントWebSocket
let ws = new ClientWebSocket();
// WebSocket接続
ws.ConnectAsync(uri, CancellationToken.None).Wait()
// サーバからメッセージを受信
let mutable result =
ws.ReceiveAsync(new ArraySegment<byte>(bytes),
CancellationToken.None).Result
message <- Encoding.UTF8.GetString(bytes, 0, result.Count)
printfn "%s" message
// メッセージ入力が続く間はWebSocketの送受信を行う
while (cond && not result.CloseStatus.HasValue) do
printf "%s" prompt
// ターミナルにメッセージを入力されたメッセージを取得
message <- stdin.ReadLine()
if (message = "") then
// Enterのみなら終了
cond <- false
else
// 入力されたメッセージをサーバに送信
ws.SendAsync(
new ArraySegment<byte>(Encoding.UTF8.GetBytes(message)),
WebSocketMessageType.Text, true, CancellationToken.None).Wait()
// サーバからメッセージを受信(エコー)
result <- ws.ReceiveAsync(new ArraySegment<byte>(bytes),
CancellationToken.None).Result
message <- Encoding.UTF8.GetString(bytes, 0, result.Count)
printfn "%s" message
// WebSocketクローズ
ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "WebSocket Closed!",
CancellationToken.None).Wait()
0 // mainの終了
WebSocketサーバ(Bun1.1)
// Bun 1.1 WebSocket is stable
// https://bun.sh/blog/bun-v1.1#websocket-is-stable
// WebSocketサーバ クライアントから受信したメッセージをそのまま送り返す
// クライアントから先に切断すること
// Bun 1.1対応
// bun run ソースファイル名.js
Bun.serve({
port: 5080,
fetch(req, server) { // サーバの処理
// WebSocketはURLの末尾/wsで受け付ける
if (server.upgrade(req) && new URL(req.url).pathname === "/ws") {
return; // レスポンスは出力しない
}
return new Response("Upgrade failed", { status: 500 });
},
websocket: { // WebSocketの処理
open(ws) { // WebSocketクライアントが接続されたとき
console.log("WebSocket Opened.");
ws.send("WebSocketサーバに接続しました");
},
message(ws, message) { // メッセージを受信したとき
console.log("message:", message);
ws.send(message);
},
close(ws) { // WebSocketクライアントが終了したとき
console.log("WebSocket Cloased.");
}
},
});
結果
// クライアント
WebSocketサーバに接続しました (サーバから受信した文字列)
ws> こんにちはWebSocket! (入力した文字列)
こんにちはWebSocket! (サーバから受信した文字列))
ws> クライアントはASP.NET Core
クライアントはASP.NET Core
ws> サーバはBun 1.1
サーバはBun 1.1
ws> (Enterのみで終了)
// サーバ
WebSocket Opened.
message: こんにちはWebSocket! (クライアントから受信したメッセージ)
message: クライアントはASP.NET Core
message: サーバはBun 1.1
WebSocket Cloased.
Discussion