💎
それ、F#でやってみました - WebSocket (サーバ:ASP.NET Core + クライアント:Bun 1.1)
ASP.NET Core Minimal APIを使ってF#で受信した内容をそのまま送り返すWebSocketサーバを作成してみました。WebSocketのクライアントはBun1.1で作成しました。
サーバ:Bun 1.1 + クライアント:.NET ClientWebSocketはこちら
WebSocketサーバ(Program.fs)
// ASP.NET Core での Websocket のサポート
// https://learn.microsoft.com/ja-jp/aspnet/core/fundamentals/websockets?view=aspnetcore-9.0
// WebSocketサーバ 受信したものをそのまま返す(エコー)
// クライアントから先に切断すること
// .NET 9 Preview 3 対応
// dotnet new web -lang f# -o ディレクトリ名
// cd ディレクトリ名
// (Program.fsを編集)
// dotnet run
open System
open System.Net.WebSockets
open System.Text
open System.Threading
open System.Threading.Tasks
open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Http
// WebSocketサーバ(エコー)
let echo (websocket: WebSocket) = task {
// 受信バッファ
let buffer = Array.zeroCreate<byte> (1024 * 4)
// WebSocket受信
let mutable receiveSocket = websocket.ReceiveAsync(
new ArraySegment<byte>(buffer), CancellationToken.None).Result
while (not receiveSocket.CloseStatus.HasValue) do
// 受信した内容を表示
printfn "Received: %s" <|
Encoding.UTF8.GetString(buffer[0..receiveSocket.Count])
// 受信した内容を送り返す(エコー)
websocket.SendAsync(
new ArraySegment<byte>(buffer, 0, receiveSocket.Count),
receiveSocket.MessageType,
receiveSocket.EndOfMessage,
CancellationToken.None) |> ignore
// WebSocket受信
receiveSocket <- websocket.ReceiveAsync(
new ArraySegment<byte>(buffer), CancellationToken.None).Result
// クローズ
websocket.CloseAsync(
receiveSocket.CloseStatus.Value,
receiveSocket.CloseStatusDescription,
CancellationToken.None) |> ignore
}
// メイン(エントリーポイント)
[<EntryPoint>]
let main args =
let url = "http://127.0.0.1:5080"
let builder = WebApplication.CreateBuilder(args)
let app = builder.Build()
// WebSocket設定
app.UseWebSockets() |> ignore
// ミドルウェア(middleware)
app.Use(Func<HttpContext, RequestDelegate, Task>(fun ctx next ->
// URLの末尾が/wsのとき
if (ctx.Request.Path.Value = "/ws") then
// WebSocketを受信したら
if (ctx.WebSockets.IsWebSocketRequest) then
// 受信した内容を取得
let websocket = ctx.WebSockets.AcceptWebSocketAsync().Result
// エコー処理
echo websocket
else
// WebSocketでなければステータスコード400
task {
ctx.Response.StatusCode <- StatusCodes.Status400BadRequest
}
else
// 次のミドルウェアへ
next.Invoke(ctx)
)) |> ignore
// 実行
app.Run url
0 // Exit code
WebSocketクライアント(Bun1.1)
// Read from stdin with Bun
// https://bun.sh/guides/process/stdin
// Bun 1.1 WebSocket is stable
// https://bun.sh/blog/bun-v1.1#websocket-is-stable
// bun run websocket_example.ts
// WebSocketクライアント サーバに文字列を送信、受信した文字列を表示
// クライアントから先に切断すること
// Bun 1.1対応
const url = "ws://127.0.0.1:5080/ws"; // アクセスするサーバ
const prompt = "ws> "; // メッセージ入力プロンプト
// WebSocketサーバにアクセス
const ws = new WebSocket(url);
// サーバから受信したとき
ws.addEventListener("message", ({data}) => {
console.log("Received:", data); // 受信した内容を表示
process.stdout.write(prompt); // プロンプトを表示
});
// サーバの接続したとき
ws.addEventListener("open", async () => {
process.stdout.write(prompt); // プロンプトを表示
for await (const line of console) { // ターミナル画面から1行ずつ入力
if (line == "") break; // 何も入力されなければ終了
ws.send(line); // 入力された文字列をサーバに文字列を送信
}
ws.close(); // クローズ
});
結果
// クライアント
ws> こんにちはWebSocket
Received: こんにちはWebSocket
ws> WebSocketサーバに送信
Received: WebSocketサーバに送信
ws> サーバに送信した内容がそのまま送り返される
Received: サーバに送信した内容がそのまま送り返される
ws> (入力せずEnterで終了)
// サーバ
Received: こんにちはWebSocket
Received: WebSocketサーバに送信
Received: サーバに送信した内容がそのまま送り返される
Discussion