using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web; using System.Web.Http; // Namespace for Web Sockets classes. using Microsoft.Web.WebSockets; namespace Chat.Controllers { public class ChatController : ApiController { // This function handles HTTP "GET" requests to the URL pattern "api/Chat". // - The client will ping this URL, to indicate it wants to start having a Web Sockets conversation with the server. // - The client will also pass a username parameter, indicating the name of the user (the client web page will get this info from the user). public HttpResponseMessage Get(string username) { // This is how a server in ASP.NET MVC4 says, "Yes, I support Web Sockets". // - It also creates a "handler" object to handle all subsequent Web Sockets messages from the client. HttpContext.Current.AcceptWebSocketRequest(new ChatWebSocketHandler(username)); // Return an HTTP response to the client to say, "OK then, let's switch our conversation from HTTP to the Web Sockets protocol. return Request.CreateResponse(HttpStatusCode.SwitchingProtocols); } // This is how you implement a Web Sockets handler class in MVC 4. // - Inherit from WebSocketHandler, and handle different types of message from the client. // - Note, there will be a separate instance of this class for every client. class ChatWebSocketHandler : WebSocketHandler { // Keep a collection of all clients that have connected over Web Sockets. private static WebSocketCollection _chatClients = new WebSocketCollection(); // Remember the name of the current user (i.e. the particular client connected to this specific Web Sockets socket). private string _username; // Constructor, invoked during the initial connection request from the client. public ChatWebSocketHandler(string username) { _username = username; } // Handle the "Open" event (occurs when the Web Sockets connection has been opened successfully). public override void OnOpen() { // Keep track of all the clients. _chatClients.Add(this); } // Handle the "Message" event (occurs whenever a client sends data to its Web Sockets server socket). public override void OnMessage(string message) { // Broadcast the message to all the clients. _chatClients.Broadcast(_username + ": " + message); } // Handle the "Close" event (occurs when the Web Sockets connection is closed). public override void OnClose() { // Forget this connection. _chatClients.Remove(this); // Tell all clients that this particular client has left the chat room! _chatClients.Broadcast("[" + _username + " has left the chat room]"); } } } }