Wednesday, September 11, 2013

WebSockets in .NET 4.5: System.Net.WebSockets.ClientWebSocket vs Windows.Networking.Sockets.MessageWebSocket

Props to this guy's example project on how to implement a simple WebSocket using System.Net.WebSockets in .NET 4.5. Another good example is here.

I am working on a Windows Store App (WinRT, Metro, Win 8, or whatever name they are trying to market this under currently) and a .NET 4.5 application. Both will be using a WebSocket to talk to the same server.

The WinRT Windows.Networking.Sockets.MessageWebSocket is a wonderfully simple way to use a WebSocket to send and receive strings back and forth. Microsoft has a nice sample project here.

The .NET 4.5 System.Net.WebSockets.ClientWebSocket is just the opposite. See aforementioned blog for a 'simple' example.

Please see both sample projects for details: MessageWebSocket, ClientWebSocket

Two things make the MessageWebSocket really easy to use. First, it has a messageRecieved event handler, so all you need to handle incoming messages is attach a method thusly:

messageWebSocket.MessageReceived += MessageReceived;

See the sample project for the MessageRecieved implementation.

ClientWebSocket requires wrapping the Send and Receive actions in tasks and monitoring the receive buffer with a loop. Reminds me of old time socket monitoring. I though WebSockets were supposed to make my life simpler?

Secondly, MessageWebSocket provides a DataWriter so all you have todo to read or write strings is set the message type, grab the reader, and send a string.

//set the message type
messageWebSocket.Control.MessageType = SocketMessageType.Utf8;
//wrap the output in a DataWriter
messageWriter = new DataWriter(messageWebSocket.OutputStream);
//put a string on the writer
// Send the data as one complete message.
await messageWriter.StoreAsync();

Compare this to the ClientWebSocket in .net 4.5:

byte[] sendBytes = Encoding.UTF8.GetBytes(message);
  var sendBuffer = new ArraySegment<byte>(sendBytes);
  await socket.SendAsync(
      endOfMessage: true,
      cancellationToken: cts.Token);

byte[] seriously? I already have a string why would I want to revert to such a low level wrapper?

Reading messages is similarly easy in MessageWebSocket vs ClientWebSocket. See the example projects for details.


Its good to have all the options provided in the System.Net.WebSockets namespace, but the end of the day, a WebSocket should make my life easy when all I need to do is send and receive some strings (json for example). I find it vexing this is provided for Windows Store Apps, but they don’t provide the same thing across platforms.

If I iron this out I’ll try to get a sample project uploaded showing how to get behavior similar to MessageWebSocket while using ClientWebSocket. No timeframe on this, sorry.