Upgrade to Pro — share decks privately, control downloads, hide ads and more …

UnityでSystem.Net.WebSocketsなWebSocketサーバが動かないので...

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

UnityでSystem.Net.WebSocketsなWebSocketサーバが動かないのでUnity Monoのコードを覗いてみた / about implementing websocket server with unity mono

C# Kaigi 2026でLT登壇した資料です
https://csharpkaigi.net/talks/lt-unity-websocket

Avatar for にー兄さん

にー兄さん

September 19, 2026

More Decks by にー兄さん

Other Decks in Programming

Transcript

  1. にー兄さん ソフトウェアエンジニア@HoloLab inc. Babylon.js勉強会運営 Iwaken Lab. Microsoft MVP for Developer

    Technologies (2024~) 好きな技術 Babylon.js / WebXR Device API / Android XR / 3D Gaussian Splatting @ninisan_drumath @drumath2237
  2. 実装のイメージ HttpListener で接続リクエストを WebsoketContext にUpgrade var _listener = new HttpListener();

    // ... var context = await _listener.GetContextAsync(); HandleClientAsync() 内でWebSocketの受信・送 信 while (socket.State == WebSocketState.Open) { var result = await socket.ReceiveAsync( buffer, token ); var message = Encoding.UTF8.GetString( buffer, 0, result.Count ); if (!context.Request.IsWebSocketRequest) { context.Response.StatusCode = 400; context.Response.Close(); return; } オウム返しするだけ var wsContext = await context.AcceptWebSocketAsync(null); var socket = wsContext.WebSocket; _ = HandleClientAsync(socket, token); } // var response = Encoding.UTF8.GetBytes( $"Echo: {message}" ); await socket.SendAsync( response, WebSocketMessageType.Text, true, token );
  3. これらは.NET Standard 2.0/2.1でサポート Unityでも動きそうな気がする var context = await _listener.GetContextAsync(); if

    (!context.Request.IsWebSocketRequest) // { context.Response.StatusCode = 400; context.Response.Close(); continue; } なぜか上手く判定されない ここで // NotImplementedException var wsContext = await context.AcceptWebSocketAsync(null); var socket = wsContext.WebSocket; _ = HandleClientAsync(socket, token); HttpListenerContext が上手く動いてくれない
  4. Unity-Technologies/mono Unity Technologiesのリポジトリに Monoのフォークがある ディレクトリ構成 mono ├─ mono/ <------------------- Mono

    Runtime ├─ mcs/ │ ├─ mcs/ <------------- Mono C# │ ├─ class/ │ │ ├─ referencesource/ .NET Core │ │ ├─ System/ C# │ │ └─ ... │ └─ ... └─ ... のコア実装 コンパイラの実装 参考用の のコードがあるらしい よく見る クラスライブラリのコード
  5. 実際のコードを見てみる mcs/class/System/System.Net/HttpListenerRequest.cs うまく動作しなかった部分を見ると、 [MonoTODO] というアトリビュートがついていた 実装が不十分なコードになっているっぽい? 実際のコードを確認することで Unity Monoで動作しない裏付けが取れた [MonoTODO]

    public bool IsWebSocketRequest { get { return false; } } mcs/class/System/System.Net/HttpListenerContext.cs [MonoTODO] public Task<HttpListenerWebSocketContext> AcceptWebSocketAsync (string subProtocol) { throw new NotImplementedException (); }
  6. 関連・参考 HttpListener and Websockets(Unity Discussion) https://discussions.unity.com/t/httplistener-and-websockets/820948 Websocket Server in Standalone

    build(Unity Discussion) https://discussions.unity.com/t/websocket-server-in-standalone-build/832108 Unity で System.Net.WebSockets を使ったゲームサーバー書こうとしたらうまくいかない(noir_neo’s blog) https://noir-neo.hatenablog.com/entry/2018/03/17/001718 Path to CoreCLR, 2026: Upgrade Guide(Unity Discussion) https://discussions.unity.com/t/path-to-coreclr-2026-upgrade-guide/1714279