Click here to Skip to main content
14,028,075 members
Click here to Skip to main content
Add your own
alternative version

Tagged as


48 bookmarked
Posted 10 Jul 2013
Licenced CPOL

Using WebSocket in .NET 4.5 (Part 3)

, 15 Jul 2013
Rate this:
Please Sign up or sign in to vote.
Using WebSocket in WCF service and communicating with the service in client applications or JavaScript on web pages


Part 1 gives an overview of the WebSocket protocol and .NET WebSocket support. Part 2 demonstrates how to use WebSocket in traditional ASP.NET and MVC 4 web applications. 

In this article, I will demonstrate how to use WCF to host a WebSocket service and write a client application. I will also show how to communicate with a WCF WebSocket service using JavaScript in a web page.

  • is the sample code of the WCF WebSocket service with a WCF client application.
  • is the sample code of the WCF WebSocket service with a web page and JavaScript.


To enable WebSocket on the server side, please refer to Part 1.

Host Service

In WCF 4.5, netHttpBinding and netHttpsBinding have been re-implemented to support WebSocket. And to make a WCF service serve the client through WebSocket, we should set CallbackContract for the ServiceContract attribute in the service interface declaration. For example:

[ServiceContract(CallbackContract = typeof(IWSChatCallback))]
public interface IWSChatService
    [OperationContract(IsOneWay = true)]
    Task SendMessageToServer(string msg);

The SendMessageToServer method will be called by the client and the msg argument is the message sent by the user. So the server should implement this method to handle the msg received from the client. IsOneWay should be set to true for the OperationContract attribute because the client should not wait for the return value of the service method call in duplex communication. CallbackContract is bound to IWSChatCallback which is declared as below:

interface IWSChatCallback
    [OperationContract(IsOneWay = true)]
    Task SendMessageToClient(string msg);

The SendMessageToClient method will be called by the server and the msg argument is the message sent by the server. So the client should implement this method to handle the msg received from the server. Again, IsOneWay should be set to true because the server should not wait for the return value of the callback method call in duplex communication.

Let’s simply implement IWSChatService as an echo server:

public class WSChatService : IWSChatService
    public async Task SendMessageToServer(string msg)
        var callback = OperationContext.Current.GetCallbackChannel<IWSChatCallback>();
        if (((IChannel)callback).State == CommunicationState.Opened)
            await callback.SendMessageToClient(
                string.Format("Got message {0} at {1}", 
                msg, DateTime.Now.ToLongTimeString()));

The service just decorates the message received from the client and calls SendMessageToClient to send the decorated message to the client.

Then we need to modify web.config to add a protocol mapping schema in the <system.serviceModel> tag like:

  <add scheme="http" binding="netHttpBinding"/>

The default netHttpBinding and netHttpsBinding will transfer data in Binary SOAP format. If you want to use Text SOAP format, you could create a customized configuration and set messageEncoding to “Text” like:

  <add scheme="http" binding="netHttpBinding" bindingConfiguration="textWSHttpBinding"/>
    <binding name="textWSHttpBinding" messageEncoding="Text"/>

OK. The WCF WebSocket service gets ready after I build it.

Client Application

To write a WCF client application, I create a console application and add the previous WCF service to Service References. Then I implement the IWSChatServiceCallback interface declared previously on the server:

internal class CallbackClient : IWSChatServiceCallback
    public void SendMessageToClient(string msg)

In the SendMessageToClient method, I just display the message received from the server.

The program’s main function looks like:

class Program
    static void Main(string[] args)
        var context = new InstanceContext(new CallbackClient());
        var client = new WSChatServiceClient(context);
        while (true)
            Console.Write("Input (\"Exit\" to exit):");
            string input = Console.ReadLine();
            if (input.ToUpperInvariant() == "EXIT")

Don’t forget to modify the endpoint address in App.config to point to the correct machine name, domain name, or IP address.

Again to emphasize, the client application can only work on Windows 8, Windows Server 2012, and above.

JavaScript in Web Page

By using netHttpBinding and netHttpsBinding, all data transferred in a WCF WebSocket connection is in SOAP format (Binary or Text). To communicate with the WCF WebSocket service with JavaScript code in the web page, I have to parse the SOAP by myself.

To avoid SOAP, I need to create and use a custom binding as below:

    <binding name="textWSHttpBinding">
        <webSocketSettings transportUsage="Always"          

  <add scheme="http" binding="customBinding" 


I use byteStreamMessageEncoding to specify the data should be transferred as byte stream instead of SOAP. In webSocketSettings, transportUsage is set to Always to enable the WebSocket protocol regardless of the contract; createNotificationOnConnection must be set to “true” to notify the client when connection is established.

The service interface and implementation need to change as well. I modified IWSChatService and IWSChatCallback as below:

[ServiceContract(CallbackContract = typeof(IWSChatCallback))]
public interface IWSChatService
    [OperationContract(IsOneWay = true, Action = "*")]
    Task SendMessageToServer(Message msg);
interface IWSChatCallback
    [OperationContract(IsOneWay = true, Action="*")]
    Task SendMessageToClient(Message msg);

I change the type of the msg argument from string to Message (System.ServiceModel.Channels) which will wrap my UTF-8 encoded text. Then I re-implement IWSChatService as below:

public class WSChatService : IWSChatService
    public async Task SendMessageToServer(Message msg)
        var callback = OperationContext.Current.GetCallbackChannel<IWSChatCallback>();
        if (msg.IsEmpty || ((IChannel)callback).State != CommunicationState.Opened)
        byte[] body = msg.GetBody<byte[]>();
        string msgTextFromClient = Encoding.UTF8.GetString(body);
        string msgTextToClient = string.Format(
            "Got message {0} at {1}",
        await callback.SendMessageToClient(
    private Message CreateMessage(string msgText)
        Message msg = ByteStreamMessage.CreateMessage(
            new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgText)));
        msg.Properties["WebSocketMessageProperty"] =
            new WebSocketMessageProperty 
            { MessageType = WebSocketMessageType.Text };
        return msg;

The client side need not implement IWSChatCallback. My JavaScript code is very similar to the example in Part 2:

<!DOCTYPE html>
<html xmlns="">
    <title>WebSocket Chat</title>
    <script type="text/javascript" src="Scripts/jquery-2.0.2.js"></script>
    <script type="text/javascript">
        var ws;
        $().ready(function () {
            $("#btnConnect").click(function () {
                ws = new WebSocket("ws://" + window.location.hostname
                    + "/WcfWSChatForWeb/WSChatService.svc");
                ws.onopen = function () {
                ws.onmessage = function (evt) {
                ws.onerror = function (evt) {
                ws.onclose = function () {
            $("#btnSend").click(function () {
                if (ws.readyState == WebSocket.OPEN) {
                else {
                    $("#spanStatus").text("Connection is closed");
            $("#btnDisconnect").click(function () {
    <input type="button" value="Connect" id="btnConnect" />
    <input type="button" value="Disconnect" id="btnDisconnect" /><br />
    <input type="text" id="textInput" />
    <input type="button" value="Send" id="btnSend" /><br />
    <span id="spanStatus">(display)</span>


Next in Part 4, I will demonstrate how to use Microsoft.WebSockets.dll.

Related Links 

Using WebSocket in .NET 4.5: 


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Zhuyun Dai
China China
Over 10-years experience in using Microsoft technologies.
At present, working as the architect of a clustered real-time data delivery and visualization system, responsible for the design of component architecture, product packaging and deployment, also targeting private cloud solutions for future.

You may also be interested in...


Comments and Discussions

QuestionCan WCF server support multiple operation contract ?? Pin
Member 175416519-Mar-15 23:34
memberMember 175416519-Mar-15 23:34 
QuestionSending Server Messages Pin
Member 1152245213-Mar-15 2:49
memberMember 1152245213-Mar-15 2:49 
Questionhttps custombinding not working Pin
Member 109030586-Feb-15 3:47
memberMember 109030586-Feb-15 3:47 
I've redone your implementation and the custom bindings works great for http. However I'm having difficulty extending websockets to https.

After a lot of tweaking with certificates I figured it out.

Add this to your service model server side and add a unique endpoint for the https binding:

          <binding name="httpsWebSocket">
            <byteStreamMessageEncoding />
              <webSocketSettings transportUsage="Always" createNotificationOnConnection="true" />

1) Host your website with Https. Then make a self signed certificate for your https site:[^]

2) Add your certificate to your service on the server:[^]

modified 12-Feb-15 8:20am.

GeneralMy vote of 4 Pin
MB Seifollahi14-Jul-13 21:09
professionalMB Seifollahi14-Jul-13 21:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web05 | 2.8.190419.4 | Last Updated 16 Jul 2013
Article Copyright 2013 by Zhuyun Dai
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid