Part 1 gives an overview to WebSocket protocol and .NET WebSocket support.
Inthis article, I will demonstrate how to host a WebSocket server in atraditionalASP.NETorMVC 4 web application using HttpContext.AcceptWebSocketRequest
. I will show JavaScript code in client-side web page. I will also show a client-side application to communicate with the same server using theClientWebSocket
class in the System.Net.WebSockets
namespace.
WSChat.zip contains the code sample for traditional ASP.NET.
Mvc4WSChat.zip contains the code sample for MVC 4.
To enable WebSocket on the server side, please refer to Part 1.
To host a WebSocket server, I create a custom HTTP handler to accept client WebSocket connection requests and communicate with the client.
public class WSHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
if (context.IsWebSocketRequest)
{
context.AcceptWebSocketRequest(ProcessWSChat);
}
}
public bool IsReusable { get { return false; } }
private async Task ProcessWSChat(AspNetWebSocketContext context)
{
WebSocket socket = context.WebSocket;
while (true)
{
ArraySegment buffer = new ArraySegment(new byte[1024]);
WebSocketReceiveResult result = await socket.ReceiveAsync(
buffer, CancellationToken.None);
if (socket.State == WebSocketState.Open)
{
string userMessage = Encoding.UTF8.GetString(
buffer.Array, 0, result.Count);
userMessage = "You sent: " + userMessage + " at " +
DateTime.Now.ToLongTimeString();
buffer = new ArraySegment(
Encoding.UTF8.GetBytes(userMessage));
await socket.SendAsync(
buffer, WebSocketMessageType.Text, true, CancellationToken.None);
}
else
{
break;
}
}
}
}
ProcessRequest
method, I check whether
HttpContext.IsWebSocketRequest
is true. True means the request is an
AspNetWebSocket
(
System.Web.WebSockets
) request. Then I call
HttpContext.AcceptWebSocketRequest
to accept the request and establish the connection. I pass in a method as the argument. This method contains code to do the duplex communication through
AspNetWebSocketContext.WebSocket
. Here I just echo what the client has sent to the server.
Don’t forget to register the HTTP handler in web.config:
WebSocket Chat
(display)
class Program
{
private static async Task ChatWithServer()
{
using (ClientWebSocket ws = new ClientWebSocket())
{
Uri serverUri = new Uri("ws://localhost/WSChat/WSHandler.ashx");
await ws.ConnectAsync(serverUri, CancellationToken.None);
while (true)
{
Console.Write("Input message ('exit' to exit): ");
string msg = Console.ReadLine();
if (msg == "exit")
{
break;
}
ArraySegment bytesToSend = new ArraySegment(
Encoding.UTF8.GetBytes(msg));
await ws.SendAsync(
bytesToSend, WebSocketMessageType.Text,
true, CancellationToken.None);
ArraySegment bytesReceived = new ArraySegment(new byte[1024]);
WebSocketReceiveResult result = await ws.ReceiveAsync(
bytesReceived, CancellationToken.None);
Console.WriteLine(Encoding.UTF8.GetString(
bytesReceived.Array, 0, result.Count));
if (ws.State != WebSocketState.Open)
{
break;
}
}
}
}
static void Main(string[] args)
{
Task t = ChatWithServer();
t.Wait();
}
}
ClientWebSocket
(
System.Net.WebSockets
) plays the role to communicate with the WebSocket server hosted in IIS. Both
ClientWebSocket
and
AspNetWebSocket
are inherited from
System.Net.WebSockets.WebSocket
. So the usage is consistent. Note that the client application can only work on Windows 8, Windows Server 2012 and above.
Iimplement the same echo function in a MVC 4 web application. I create an ApiController
to handle WebSocket requests. In the Get
method, I still useHttpContext.AcceptWebSocketRequest
to accept and establish connections:
public class WSChatController : ApiController
{
public HttpResponseMessage Get()
{
if (HttpContext.Current.IsWebSocketRequest)
{
HttpContext.Current.AcceptWebSocketRequest(ProcessWSChat);
}
return new HttpResponseMessage(HttpStatusCode.SwitchingProtocols);
}
private async Task ProcessWSChat(AspNetWebSocketContext context)
{
WebSocket socket = context.WebSocket;
while (true)
{
ArraySegment buffer = new ArraySegment(new byte[1024]);
WebSocketReceiveResult result = await socket.ReceiveAsync(
buffer, CancellationToken.None);
if (socket.State == WebSocketState.Open)
{
string userMessage = Encoding.UTF8.GetString(
buffer.Array, 0, result.Count);
userMessage = "You sent: " + userMessage + " at " +
DateTime.Now.ToLongTimeString();
buffer = new ArraySegment(
Encoding.UTF8.GetBytes(userMessage));
await socket.SendAsync(
buffer, WebSocketMessageType.Text, true, CancellationToken.None);
}
else
{
break;
}
}
}
}
The JavaScript code in my index.cshtmlis almost the same as the example I have shown before. The only difference is the URI used to send WebSocket connection request. It follows the MVC URI style:
@{
Layout = null;
}
Index
(display)
Next in Part 3, I will demonstrate how to use WCF to host WebSocket server and how to communicate WebSocket WCF service using WCF client application or JavaScript in a web page.
Using WebSocket in .NET 4.5: