WCF WebSockets で WebSocket クライアントが提供されていることを今さら知りました。WebSocket サーバーが提供されていることは前から知っていたんですけどね。ここのところずっと Ruby や JavaScript でばかり遊んでいたので、.NET の情報にだいぶ疎くなっていました。
ちょうど WebSocket について調べていたので、せっかくだし WCF WebSockets 試してみましょうかね。お題は、WebSocket のサンプルとしては定番の、なんちゃってチャットアプリで。久しぶりに C# を書く気がする。
WCF WebSockets は下記のサイトから入手できます。
インストールしたら、いざスタート。
まずは、サーバーから作成します。Visual Studio 2010 でコンソールプロジェクトを作成して、System.ServiceModel.dll と Microsoft.ServiceModel.WebSockets.dll を参照に追加し、次のコードを書きます。
using System; using System.Collections.Generic; using System.ServiceModel; using Microsoft.ServiceModel.WebSockets; namespace WebSocketSample.Server { class Program { static void Main(string[] args) { // WebSocket のサービスをホストするには、 // 専用の WebSocketHost クラスを使う var host = new WebSocketsHost<ChatService>( new Uri("ws://localhost:1234/chat")); // WebSocket 用のエンドポイントを登録 host.AddWebSocketsEndpoint(); // サービス開始 host.Open(); Console.WriteLine("Enter で終了します。"); Console.ReadLine(); host.Close(); } } // セッションごとにサービスインスタンスを生成 [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)] public class ChatService : WebSocketsService { // チャットサーバーに接続しているセッションを格納 private static readonly List<ChatService> _services = new List<ChatService>(); public override void OnOpen() { _services.Add(this); } protected override void OnClose(object sender, EventArgs e) { _services.Remove(this); } public override void OnMessage(string value) { foreach (var service in _services) { service.SendMessage(value); } } } }
サーバー側はたったこれだけ。OnMessage(string) ではなく OnMessage(byte[]) を間違ってオーバーライドすると、SendMessage(string) で送られてくるデータを受信できないので注意。私は見事ハマりました。
次にクライアントを作成します。こちらもコンソールプロジェクトとして作成し、Microsoft.ServiceModel.WebSockets.DesktopClient.dll を参照に追加します。クライアントのコードは次の通り。
using System; using System.ServiceModel.WebSockets; namespace WebSocketSample.Client { class Program { static void Main(string[] args) { // WebSocket クライアント生成 var client = new WebSocket("ws://localhost:1234/chat"); // WebSocket サーバーからメッセージが送られてきたら // コンソールに表示 client.OnData += (sender, e) => { Console.WriteLine("from server: " + e.TextData); }; // WebSocket サーバーに接続 client.Open(); while (true) { var message = Console.ReadLine(); // 入力されたメッセージをサーバーに送信 client.SendMessage(message); } } } }
WebSocket クライアントの API は、HTML5 の WebSocket API に似ているので、調べなくても使えました。これでサーバーとクライアントの完成です。
サーバーとクライアント(2つ)を起動し、それぞれのクライアントでメッセージを入力すると、
ちゃんと WebSocket でサーバー側からプッシュされています。簡単に WebSocket でチャットアプリが書けてしまいましたよ。Microsoft++。