Tuesday, July 20, 2010

Silverlight HTML5 WebSocket client with an HTML bridge to Ajax/JavaScript

NOTE: Answering to popular demand expressed in comments to this thread, we are now making a .NET prototype implementation of a WebSocket draft specification available for download. Check out the details at http://tomasz.janczuk.org/2010/12/websockets-wcf-service-silverlight-and.html.

One of the HTML 5 initiatives is to define a duplex communication protocol called WebSocket for use between web browsers and servers. The protocol enables a number of applications that must exchange messages between the client and the server with performance characteristics that cannot be met with the HTTP protocol. In particular, the protocol enables the server to send messages to the client at any time after the WebSocket connection has been established and without the HTTP protocol overhead. This contrasts WebSocket to technologies based on the HTTP long polling mechanism available today.
A sample web chat application built using a prototype implementation of the WebSocket protocol is available at http://40interop.ep.interop.msftlabs.com/html5/wschat.html, as well as hosted in Windows Azure at http://websockets.cloudapp.net/wsdemo.html. The prototype consists of the following components:

  1. The server side of the WebSocket protocol implemented using Windows Communication Foundation (WCF) from .NET Framework 4. The endpoint at ws://40interop.ep.interop.msftlabs.com:4502/servicemodelsamples/chat.svc implements two currently considered protocol proposals: the draft-ietf-hybi-thewebsocketprotocol-00 (also referred to as version 76), and draft-hixie-thewebsocketprotocol-75. The server implementation automatically detects the version the client is using.
  2. The client side of the WebSocket protocol implementation consists of two components:
    1. A Silverlight 4 application that implements the draft-hixie-thewebsocketprotocol-75 version of the WebSocket protocol. It is available at http://40interop.ep.interop.msftlabs.com/html5/ClientBin/Microsoft.ServiceModel.Websockets.xap.
    2. A jQuery extension that determines if the web browser in which the JavaScript application is running supports the WebSocket protocol natively or not. If the browser supports the WebSocket protocol natively, the jQuery extension gets out of the way. If the browser does not support the WebSocket protocol natively but does support Silverlight 4, the jQuery extension dynamically adds the Silverlight 4 application (#1) to the page and creates a set of JavaScript WebSocket APIs that delegate their functionality to the Silverlight application using the HTML bridge feature of Silverlight. It is available at http://40interop.ep.interop.msftlabs.com/html5/js/jquery.slws.js.

Given the approach taken, the sample chat application based on WebSockets should be working in all major browsers (Internet Explorer, Firefox, Chrome, Safari, Opera). 

Mike Taulty has an excellent post explaining in more detail the client side implementation.

65 comments:

  1. A couple of questions.
    1) The SL WebSocket code exists in the Microsoft.ServiceModel namespace. Does this mean it will eventually become officially supported Microsoft code?

    2) Can we see the server side code? I'd be interested in experimenting with this a lot more.

    ReplyDelete
  2. +1 for posting the server side code! Great Demo. Thanks.

    ReplyDelete
  3. Currently the server side code is not publicly available, but we are looking at publishing it (likely on Codeplex) in the future. WCF is looking at options to enable HTTP based duplex communication capability in future releases of .NET and Silverlight and the proposed WebSocket standard is a an option we consider very seriously.

    ReplyDelete
  4. Why the hesitation in publishing the server source?

    I (and many others) have learned from other .NET WebSocket server implementations such as this below:

    http://www.codeproject.com/KB/webservices/c_sharp_web_socket_server.aspx

    I imagine that your source would be similarly helpful. It's not like their aren't similar implementations publicly available.

    ReplyDelete
  5. Current prototype implementation of the server side of the Websocket protocol involves extensive modification of WCF code in .NET 4.0 and cannot be shared in the current state without shipping large chunks of 4.0 code itself. We are working on isolating the necessary changes and components such they don't require any changes in .NET Framework 4.0 itself but build on top of it.

    ReplyDelete
  6. Have you tried running your Silverlight implementation against another popular WebSockets server implementation such as node.js' socket.io?

    Howard

    ReplyDelete
  7. Are you going to be supporting SSL with the (perhaps) forthcoming WebSocket .NET/Silverlight implementation?

    ReplyDelete
  8. When I use the client websocket code (javascript to silverlight bridge from within IE or Firefox) to connect to a traditional web socket server (like the one available here: http://www.codeproject.com/KB/webservices/c_sharp_web_socket_server.aspx?msg=3422430) the connect will always fail (it just closes the connection immediately). Using the same client code in Chrome or Safari (where Websockets are natively implemented) works correctly. Is there something special in the server that the 75 protocol requires that I am missing?

    ReplyDelete
  9. The Silverlight implementation of websockets is based on System.Net.Socket and as such is subject to the same port restrictions. The prototype Silverlight websocket shown here can only communicate over ports 4502-4534. In addition, the target server must expose clientaccesspolicy.xml at the root of the domain over the HTTP protocol to allow such connection, as it is considered a cross-domain call from Silverlight runtime perspective. Some of these restrictions could be removed should a websocket implementation ship with a future release of Silverlight (and therefore be part of the trusted platform code).
    Given these restrictions, we did not even attempt to do any interop testing of the Silverlight client against other websocket servers. The server implementation has been tested with all browsers that natively support websockets, as well as the Silverlight client.
    Current server protototype does not support SSL, we are looking at enabling this feature going forward. I believe it is key to support SSL if and when Websockets become part of .NET framework.

    ReplyDelete
  10. Yeah, sorry - I should have said. I knew about the port restriction (you throw an exception in that case) and clientaccesspolicy.xml requirements, and accommodated for those. I'm just seeing what appears to be another restriction where the 75 protocol is failing silently. You try to connect and it responds by simply closing the connection instead. Seemed odd, and I wondered if you knew off the top what it could be.

    No worries though, and thanks for posting!

    ReplyDelete
  11. Ravi, if there is a public endpoint I can access, I can look into it.

    ReplyDelete
  12. Tomasz, I don't have anything public for this right now. Thanks for the offer, though.

    ReplyDelete
  13. HI Tomasz,

    Has there been any movement on posting of the server-side code?

    Thanks!

    ReplyDelete
  14. Metaman,

    we are actively working towards a release of the websockets server components that can be used to build websocket WCF services on top of .NET 4.0.

    Are you interested in the source code in particular, or would a binary only release work just as well for you? Do you need to modify the implementation or do you just want to use it to build a websocket service and/or client?

    The challenge we have is that the websocket implementation leverages a large section of WCF code. For a full source code release of the websocket functionality we would have to also release a large chunk of WCF code, which we are reluctant to do for a variety of non-engineering reasons.

    ReplyDelete
  15. It would be interesting to see the source code but in reality a binary-only release is all I really need. Have you any rough timescales for a possible binary release? Q4? Next year?

    Thanks.

    ReplyDelete
  16. Thanks for the data. We are targeting Q4, hopefully the beginning of it.

    ReplyDelete
  17. Sounds good. Looking forward to checking it out!

    ReplyDelete
  18. Good job.
    One more waiting for server side code!

    ReplyDelete
  19. I'm eagerly awaiting the server side code to this as well. I'd be happy with a binary.

    ReplyDelete
  20. Hi,

    Can you atleast give the outline of the server side code apart from the HTML5 approach websockets will improve duplex behaviour. So please share the code. If possible please make a template like Silverlight enabled WCF services and other stuff and post the same in MSDN gallery

    ReplyDelete
  21. The code for websockets will be showing up on wcf.codeplex.com within a few weeks, stay tuned. (The site is not published yet as of this writing).

    ReplyDelete
  22. Hopefully this will arrive just in time. I'm looking towards building a WCF service and Silverlight client which will communicate using WebSockets, and this sounds ideal.

    Please continue to keep us updated on progress! :)

    ReplyDelete
  23. Hi,
    Thanks for the reply. My ethusazim makes me quiz you more. could you please share some highlights as to how you are planning to do this. Are you planning to provide this as separate binding or an addition tag like "" in binding behavior. I guess the latter option will be good with additional attributes for providing the address of known proxy and password. Also I suggest that encryption with SSL be forced somehow as unencrypted Web sockets packet might have problems facing transparent proxy. The transparant proxies are those for which no explict HTTP connect is issued either by your know proxy or by the browser.
    Thanks
    Venkatesh. S

    ReplyDelete
  24. hi,
    is there any possibility to implement C# server side websocket on internet to listen asp.net client request if possible plz let me know how to implement,and what changes hsould be made in web.config file.

    ReplyDelete
  25. Hi,

    I accessed the wcf.codeplex.com site today. I find that the project is still not ready. Could you please tell me by what date it will avaialble? Eagerly awaiting to see an implementation.

    ReplyDelete
  26. Hi,

    There is a valid point in what JC said on SSL. The issue is like this in any typical secured environmnet, say a corporate network, there can be known proxies and trnsparant proxies. By known proxies I mean those proxies that you know and you have configred browser and/ other client software. Transparent proxies are those that you do not know but lies in the permimeter of your intranet. What happens when communicating with web sockets is that the moment you intiate a web socket request from server/ client, the known proxies can be by passed as there as n explicit HTTP connect intruction that is sent by browser/client. But in case of transparent porxies no such instruction with a known credentials are sent and hence they strip away connection information. This leads to malformed Websocket packets. On the other hand if the packets are encrypted with SSL then these proxies check if they are encrypted and let them go without stripping. So SSL encoded packets have a large survival rate without damage through transparent proxies. Hence SSL support is defintely required if we were to truly say WCF supports Websockets. In fact like a customAuthnetication mode setting where a certificate encryption is enforced, web sockets implementation should also enforce SSL authnetication

    ReplyDelete
  27. Venkatesh, I completely agree SSL support in websockets is going to be be crucial in traversing intermediaries.

    ReplyDelete
  28. Hi,
    Will you be releasing this project today at PDC10. I do not see that in the agenda. Can you please tell me quickly at what time this Web socket implementation for WCF will be available.

    Thanks

    ReplyDelete
  29. I imagine it will be after the Glenn Block talk 'Building Web APIs for the Highly Connected Web' (4pm GMT)

    ReplyDelete
  30. Hi,

    Does this have support for Web sockets? If so how to do that? Is support for websockets available as a separate protocol or as a separate tab under binding behaviour under basicHTTP binding

    ReplyDelete
  31. Websockets are not part of the bits released on wcf.codeplex.com today at PDC. We are still not ready at this point to release WCF websockets support publicly, but we will as soon as all remaining issues are resolved. I appreciate your interest as I realize this is a broadly desired feature.

    In the meantime, if you can share what problem you are trying to address with websockets, perhaps I can offer a suggestion for an alternative that is available today.

    ReplyDelete
  32. Hi Tomek,
    I'm looking for a pure push capability unlike the polling duplex contract. I would like the server to be able to push content to clinet over http across firewalls and without client polling the server at regular intervals or both having to implemnet a duplex contract. I guess this is one of the main feature that is offered by web sockets. If you could provide me a way to do that with this release then it will be great

    ReplyDelete
  33. Like Venkatesh, I need a Silverlight client / WCF service with push capabilities, and WebSockets excel over the current polling duplex method in every way.

    The sample in this post is great but I'm concerned about its inability to connect to port 80 as this - unless I'm misunderstanding - is one of the major benefits of WebSockets when overcoming things such as firewalls and proxies which - for a web-based, browser-hosted application should never be an issue.

    Do you have a rough timeframe on when we might see WebSockets support released? Thanks.

    ReplyDelete
  34. Tomasz,

    I am also very much interested in WebSocket messaging. Especially with Silverlight fall back. Of course, this feature will become hot with IE9 and FF4 releases, but I'd start ASAP. And I definitely need pub/sub notification service with push-to-browser capabilities for my current project.

    ReplyDelete
  35. Venkatesh, perhaps you can contact me directly at tomasz at janczuk dot org, I would like to better understand the requirements of the application you are building before recommending an approach.

    ReplyDelete
  36. Barguast, you are right that one of the design goals for the websocket protocol is that it can traverse firewalls similarly to the HTTP protocol. As such it is indeed key to support this protocol over port 80 and 443 (with SSL). When you say "websockets excel over the current polling duplex method in every way" do you have any particular characteristic of the protocol in mind that you care about more than others in the context of your application?

    At this point we don't have a timeline for delivering websockets but we are actively working on resolving all remaining issues.

    ReplyDelete
  37. Igor, please note websockets is just a duplex messaging protocol, it does not provide any pub\sub capabilities on its own. You may be interested in checking out http://laharsub.codeplex.com if you need a pub\sub solution for web clients.

    ReplyDelete
  38. @Tomasz. Thanks for your reply. What I'm looking for is a protocol that will provide two-way communication with minimal latency, overhead, and maximal performance. Standard TCP would be ideal if it weren't for the fact that ports need to be open, firewalls and proxies needs to be configured and bypassed, etc. As far as I've been able to tell, WebSockets does all of this.

    I'm glad to hear that port 80 and 443 will be supported. I understand the commercial Kaazing implementation does, so I can see it's possible.

    I'm really looking forward to seeing WebSockets fully supported. I don't want to nag, but if you do have any idea of when we'll see it then please let me know. Otherwise, please just keep us informed!

    Thanks again,
    Barguast

    ReplyDelete
  39. Hi Tomek,

    Could you please send me a test email to my Google email. I shall then reply you from my personal email venkateshsrini3 at gmail dot com

    ReplyDelete
  40. Barguast, are you deploying your application in an environment where you have control over the client OS and browser make/model, or does it target the wild wild internet?

    ReplyDelete
  41. Ideally, the environment will be 'any browser that runs Silverlight'. That includes those that don't support the WebSocket API. Realistically, they'll all be Windows-based PCs.

    I'm more interesting in the .NET implementation of WebSockets - I wrote one myself for a console application, based on TcpClient, but that won't work in Silverlight since TcpClient isn't (nor Socket over port 80, iirc). I would guess that any Silverlight implementation would have to be based on HttpWebRequest?

    ReplyDelete
  42. Tomasz, thanks for your note. I meant exactly Laharsub for pub/sub. Just claimed that I am really interested to see websocket support there.

    ReplyDelete
  43. Tomasz, as someone who has been following this thread since July, I have been waiting for the wcf codeplex release in order to take advantage of all of the benefits you've outlined in your original post. I find it difficult to understand why your responses to these posts recently are encouraging us to pursue options other than websockets. could you provide us with some background as to why the websockets protocol was omitted from the wcf codeplex release instead of suggesting we fall back to inferior methods of simulated duplex channels? clearly you have had the websocket code available since july, and the plan for release since July 27, 2010 was to push to wcf codeplex. in august you mentioned Q4 release date, and now you're stating there is no timeline? seems like a lot of promises and not so much follow through. what gives?

    ReplyDelete
  44. Barguast, you are right that currently Silverlight applications cannot implement the websocket protocol in Silverlight over port 80 due to the the port restrictions imposed by the Silverlight runtime for security reasons. Only TCP ports 4502-3534 are available for use by Silverlight applications (http://msdn.microsoft.com/en-us/library/cc645032(VS.95).aspx). Enabling any custom TCP protocol, including websockets, to use a port other than one from this range will require changes to Silverlight runtime itself. One possible approach to enabling websockets in a Silverlight application would be to leverage the HTML bridge to access this functionality directly in the browser. However, the set of browsers supported by Silverlight is different than the set of browsers that support websockets natively, so this approach clearly will not work across all platforms supported by Silverlight.

    Regarding .NET client, the situation is much simpler from the technical standpoint. We know there are scenarios that require a firewall-traversing, client-initiated protocol for .NET clients, but I am very curious what is yours? What kind of application you are building that requires a .NET client for websockets?

    ReplyDelete
  45. Anonymous, I realize it looks like I weasel my way around providing any binding answer as to when we would release websocket support. I wish I was able to provide a clear answer to this question, but at this point we truly do not have a timeline we can commit to due to a variety of technical and non-technical issues.

    ReplyDelete
  46. @Tomasz - My scenario is that I want to provide a web client application. I want to use Silverlight for this. The application itself will be listening for events from a service and updating the client in real-time. Conceptually, it's very much the same as a chat client. I want instant updates as they arrive so polling isn't necessarily suitable. On top of that, I want as little overhead as possible to it scales well. In addition, I want to be able to connect to my service without having to configure any firewalls, proxies etc. since it's a web application and they shouldn't be exposed to any of that nonsense. This rules out a TcpClient-based connection.

    What I'm left with following this is WebSockets which seems to do everything I need. Port 80 access, (near) instant communications, and minimal overhead.

    I'm only in the planning stages at the moment, but I'd love to base my Silverlight application on WebSockets. And hopefully by the time it comes to start implementing it, WebSocket socket support will be available in some shape or form! :)

    ReplyDelete
  47. Hi Barguast,

    Since you said that your application is like a chat client, could you please see if WCF4 discover (managed or adhoc) would work for you.

    ReplyDelete
  48. Barguast, I am not sure how instant is instant enough in case of your application (is it seconds or milliseconds?), but given that you look at websockets I assume you need very low latency. It also appears you can really leverage some kind of a publish\subscribe message exchange pattern since you conceptually compare your application to a web chat. If you plan on deploying your application in Windows Azure, one technology you should check out is Service Bus. Otherwise, have a look at http://laharsub.codeplex.com, which may get you going with an HTTP long polling pub\sub solution both on premise and in the cloud. Laharsub comes with a Silverlight client (among others), and websocket support is in the plan for the future.

    ReplyDelete
  49. In terms of latency I mean 'as soon as possible', and in terms of performance I mean 'as quick as possible' and in terms of overhead I mean 'as little as possible'. I'm looking for an ideal-world solution at the moment! :)

    Many thanks for your suggestions - I'll have a look through them and see if they're do the job in the meantime.

    I don't think it'll lessen my enthusiasm for WebSockets though - again, if you can, please keep us up-to-date with their development and inclusion in Silverlight. Thanks. :)

    ReplyDelete
  50. Hi Barguast,

    Did you try LaharSub. That is pub/sub framework and should scale well.

    Thanks and regards

    ReplyDelete
  51. I'll do that.

    BTW, I think the chat service for this example is down?

    ReplyDelete
  52. Barguast, the chat samples are up as of right now.

    ReplyDelete
  53. Tomasz

    Websockets have a lot of attention, since it predicts to overcome the existing duplex channel restrictions there is with Silverlight/WCF.

    Currently we have a rich WPF app that reaches WCF services over the ServiceBus (AppFabric). Using Publish/Subscribe the server updates all connected clients, pushing notifications.
    Due to the tcp relaybinding (with WS trust and saml) it is very fast.
    In order to move the solution to Silverlight, we really need to have duplex without limits.

    What I'd like to have is a WCF with WebSockets protocol underneath. Exposed through the ServiceBus, Silverlight Clients would access it over the ServiceBus using a Binding.
    Is this scenario the one you are working on or did I misunderstand?

    Thanks and regards

    ReplyDelete
  54. I've had some success in creating a WebSocket implementation (although it requires full trust at the moment). However, I've now realised that SslStream - a requirement for supporting wss - is not supported in Silverlight. What a show stopper! It feels like Silverlight is out to get me.

    Do you perhaps have any advice for getting around this problem?

    ReplyDelete
  55. Barguast, lack of SSL support in Silverlight is indeed the largest missing piece for implementing Websockets on that platform. Lacking SSL support in Silverlight runtime I can only see two ways of enablnig websockets in Silverlight:

    1. Reach to the underlying browser implementation using HTML bridge. This would only work if the browser natively supports websockets, and so you would not achieve the same browser coverage as Silverlight offers.

    2. Implement SSL completely in managed code. This would be a Herculean effort: one would have to provide the necessary cryptographic support as well as resolve the issue of validating the server X.509 certificate. Since certificate validation is not something that is available first class in Silverlight, one would have to either ship the certificate to a trusted server for validation, or fake a regular HTTPS call to the websocket endpoint just to leverage the regualar browser's mechanism of certificate validation for HTTPS calls.

    ReplyDelete
  56. Presumably (I could well be wrong!) the HttpWebRequest class supports SSL? Perhaps a WebSocket implementation should be based on those rather than a socket (which brings other limitations, such as port restrictions). My latest attempt at what seems like achieving the impossible has been based on this class, and while I've got around some of the limitations (namely preventing GET requests from having a body, which is necessary for the 76 protocol) with some reflection-based hacking, some of the others seem harder to get around which is making it impossible to initiate the handshake. Very frustrating. Perhaps someone else will have more luck.

    ReplyDelete
  57. Barguast, I think trying to hack around HttpWebRequest in Siverlight to achieve Websockets is a dead end. Silverlight's HttpWebRequest is just a thin wrapper around native HTTP stacks specific to PC and Mac. The only viable options I know about for websocket implementation on top of Silverlight 4 are the two I listed above.

    ReplyDelete
  58. So the two barriers seem to be: No SSL support, and no port 80 support. The latter being solved by running OOB, and the former being unsolvable without implementing a huge amount of SSL support code.

    I hope Microsoft are aware of these deficiencies and are inclined to support your implementation of WebSockets in future (i.e. Silverlight 5). Until then, I don't think Silverlight is the platform for me. :(

    ReplyDelete
  59. Tomasz,

    I'm just curious, do you think there is still a chance of this happening in Q4? We're quickly approaching December and this is something I'd love to have for an instant messenger project I'm designing. Personally, I'm not too interested in source code, a binary would do!

    Thanks and keep up the great work!

    ReplyDelete
  60. dman,

    at this point it does not look like we will ship websockets implementation in Q4.

    ReplyDelete
  61. Disappointing, but I understand. I'd prefer an MS solution, but I guess I'll work on using Nugget instead. Thanks for the answer though!

    ReplyDelete
  62. Does Silverlight 5 have any extra features that will facilitate a WebSocket implementation? Namely, allowing socket connections over port 80/443 and supporting SSL? As far as I've seen, the answer is a no. Really disappointing if so.

    ReplyDelete
  63. This is a great work over Silverlight development, I was looking for this kind of blog.

    ReplyDelete
  64. Hi,

    I was exploring WebSockets samples on html5labs and found that there is Silverlight based implementaiton as well. I just wanted to know whether Silverlight is a dependency and we cannot use this sample without installing silverlight or is it possible to use this sample even without installing Silverlight?

    In short, can we avoid using files mentioned in point 4,5 and 6 under Using The Libraries section of ReadMe found at http://html5labs.interoperabilitybridges.com/media/47685/readme.htm

    Any help?

    Thanks,
    Asim

    ReplyDelete
  65. HTML5 designers will be very much happy to work with silverlight. HTML5 will definitely improve the status of silverlight...

    ReplyDelete

My Photo
My name is Tomasz Janczuk. I am currently working on my own venture - Mobile Chapters (http://mobilechapters.com). Formerly at Microsoft (12 years), focusing on node.js, JavaScript, Windows Azure, and .NET Framework.