|
Real-time Push data from HTTP server onto MS Silverlight clients
support@udaparts.com
Contents
1. Introduction Microsoft has been working hard to bring us a new cross-platform and cross-browser technology for developing rich Internet application having many features such as multimedia, animation, graphics and audio/video playback. Starting from version 2, MS Silverlight supports .NET development languages and its integrated development environments. This is a very good approach and a very good news to .NET developers. To communicate with backend server, Silverlight uses a very limited version of Window Communication Framework (WCF), HTTP protocol (For example, the class WebRequest), and socket. In general, these approaches make a client/server request simpler, but these technologies do not have enough support to push data from a HTTP server onto Silverlight client because these technologies are either too complex to use (socket) or poor in performance and scalability (WCF PollingDuplexHttpBinding). Now, our SocketPro comes with a new adapter specifically written for making bi-directional communication between HTTP server and Silverlight super easy with better scalability. This short article is a simple tutorial to guide you use our SocketPro to push data from a simple SocketPro HTTP server to Silverlight clients. 2. Communication architecture between Silverlight and SocketPro HTTP server SocketPro has a HTTP service as shown in this article. Further, as shown in this article, it also supports pushing data from HTTP server onto browsers by use of HTTP protocol through JavaScript. SocketPro HTTP server is written with 100% non-blocking socket communication. Its special design is superbly great for developing applications requiring the feature real-time notification among all types of clients such as web browsers, desktop applications, server applications, and pocket pc/smart phone applications. You can see the particular feature here. We further extend SocketPro to support bi-directional communication between Silverlight and SocketPro specific HTTP server through JavaScript (ujsonxml.js) by writing a small (16 kilo bytes) Silverlight library (SAdapterForSilverlight.dll). The communication architecture can be simplified as the following: Your .NET Silverlight code <===> SAdapterForSilverlight.dll (C# code) <===> ujsonxml.js (JavaScript) <===> usktpror.dll (core native code) <===> SProAdapter.dll(.NET code) Note that the above left red part runs inside a browser and right blue part on server side. 3. Analyze sample code snippets There are two separate projects available for this tutorial.
Client side code: At the very beginning, you need to refer SocketPro adapter for Silverlight (SAdapterForSilverlight.dll) from your Silverlight project, and its name space like 'using SocketProAdapter.ClientSide;'. On your html or asp.net page, you'd refer SocketPro adapter for JavaScript (ujsonxml.js) before silverlight.js like the below: <script type="text/javascript" src="ujsonxml.js"></script> At this time, once a page is loaded, you can set two callbacks like the below. public Page() { InitializeComponent(); UHTTP.UChat.OnChatRequest += new DOnChatRequest(UChat_OnChatRequest); UHTTP.UChat.OnMessage += new DOnChatNotification(UChat_OnMessage); } The above code is simple. The first callback is used for tracking returning results of chat requests such as Enter, Exit, Speak and SendUserMessage. The second one is for tracking any messages from a remote SocketPro HTTP push server. Note that SocketPro adapter for Silverlight exposes one static object UHTTP, which internally has one static object UChat. The following code snippet shows you how to handle chat requests results. void UChat_OnChatRequest(CRequest Request, object Result) { switch (Request.Name) { case "enter": if (UHTTP.UChat.Chatting) { btnEnter.IsEnabled = false; btnSpeak.IsEnabled = true; } break; case "exit": btnEnter.IsEnabled = true; btnSpeak.IsEnabled = false; break; default: break; } txtMsg.Text = string.Format("Method = {0}, Result = {1}", Request.Name, Result.ToString()); } As you can see, it is really simple! The following code snippet shows you how to send a message onto other Silverlight, desktop, server and device clients through chat request Speak. Similarly, you can make other chat requests at your will. private void btnSpeak_Click(object sender, RoutedEventArgs e) { int []groups = {1,2,8}; UHTTP.UChat.Speak(txtMsgOut.Text, groups); //send a message onto groups (1 + 2 + 8) of clients } The code just speaks out how it is simple! To track all types of messages from other Silverlight, desktop, server and device clients, you can use the below code snippet. void UChat_OnMessage(CRequest Request, CHttpPush HttpPush) { switch(HttpPush.Type) { case MessageType.Normal: { string str = ""; foreach (CChatMessage cm in HttpPush.Messages)
{
string
strGroups = "[";
if (cm.Groups != null)
{
for (int
n = 0; n < cm.Groups.Length; n++)
{
if (n > 0) strGroups += ",
";
strGroups += cm.Groups[n].ToString();
}
strGroups += "]"; } if (str.Length > 0) str += "ß>"; if (cm.MethodName == "enter") str += string.Format("Sender = {0}, Message = join groups = {1}", cm.Sender, strGroups); else if (cm.MethodName == "exit") str += string.Format("Sender = {0}, Message = {1}, groups = {2}", cm.Sender, "exit", strGroups); else str += string.Format("Sender = {0}, Message = {1}, groups = {2}", cm.Sender, cm.Message, strGroups); } txtMsg.Text = str; } break; case MessageType.ServerShuttingdownGracefully: txtMsg.Text = "SocketPro HTTP push server shut down gracefully"; break; case MessageType.Timeout: txtMsg.Text = "Time out"; break; default: txtMsg.Text = "Unknown message"; break; } } Again, you can see how simple it is! The above covers all of message-related callbacks and requests, which is powerful enough to support your business requirements for real-time message among Silverlight clients, simple HTML pages, desktop applications, server applications, and device applications. For further readings, see this article here. Note that SocketPro fully supports HTTP protocol, which enables you send a HTTP request from a Silverligh onto SocketPro HTTP server. To do so, simply use an instance of CRequest inside SocketPro adapter for JavaScript as shown in the below. private void btnDoMyRequest_Click(object sender, RoutedEventArgs e) { Dictionary<string, object> map = new Dictionary<string, object>(); map.Add("Map0", 123.45); map.Add("Map1", null); map.Add("Map2", "A sample map string"); object[] AComplexStructure = new object[7]; AComplexStructure[0] = map; AComplexStructure[1] = "MyString"; AComplexStructure[2] = DateTime.Now.AddDays(-2); AComplexStructure[4] = true; AComplexStructure[6] = 34567; object[] child = new object[2]; child[0] = "myDate"; child[1] = DateTime.Now.AddDays(-5); AComplexStructure[3] = child; CRequest reqComplex = UHTTP.CreateHttpRequest("MyCall", "/MyChannel"); reqComplex.Add("Param0", m_lIndex); reqComplex.Add("Param1", 23.45); reqComplex.Add("MyParam", "A demo string"); reqComplex.Add("ABoolean", true); reqComplex.Add("ADateTime", DateTime.Now); reqComplex.Add("AnArray", AComplexStructure); reqComplex.Add("CyeMap", map); m_lIndex = reqComplex.Invoke(delegate(CRequest myReq, string strResult) { HtmlPage.Window.Alert(strResult); }); } We purposely show you how to send a complex request named as MyCall onto a remote HTTP server through channel (/MyChannel). Note the static object UHTTP exposes a static method CreateHttpRequest used for creating an empty HTTP request. Internally, SocketPro adapter for Silverlight constructs a JSON object through SocketPro adapter for JavaScript (ujsonxml.js) and send it onto server by default. You can use the above code to send any request easily. Note the class CRequest method Invoke supports synchronous computing for same-domain HTTP request, although we'll use asynchronous computing by default. However, technically it is not possible to do synchronous computing for cross-domain (site) HTTP request. The last important note is that SocketPro supports both same-domain and cross-domain (or site) chat request and message on the fly silently. If a message or request is same-domain, it will use AJAX. Otherwise, it uses JavaScript tag to complete it silently for you. Server side code: It is superbly simple too! We have hidden all of HTTP chat and message from you. All you need to do is to use the class CHttpPushPeer. Because this sample server project is the same one as shown in this article, we like you to read this article here. As long as you read it, you are expected to know how to enable HTTP server push on server side. Here is the only code snippet which we like you to know. It shows you how to handle a HTTP request from a browser page or Silverlight client. protected override string OnProcessingRequest(string strMethod, string strVersion, string strId, Dictionary<string, object> mapParams){ switch (PathName){ case "/MyChannel":{ CMyCall myCall = new CMyCall();myCall.method = strMethod; myCall.version = strVersion; myCall.callIndex = strId; myCall.parameters = mapParams;
System.Web.Script.Serialization. JavaScriptSerializer jss = new System.Web.Script.Serialization.JavaScriptSerializer(); string str = jss.Serialize(myCall); Console.WriteLine(str); return str;} default: break;} throw new Exception("Request not supported");} Here we simply serialize a request back into a JSON string and echo back request as returning result string. Note that you can also throw an exception. The exception message will be transferred onto its browser. 4. Comparison to socket and WCF PollingDuplexHttpBinding Our SocketPro approach has a lot of advantages over socket and WCF with PollingDuplexHttpBinding as well as other implementations. Here is the list.
6. FAQs a. Does SocketPro adapter for
Silverlight supports SSL/TLS for secure communication? b. Can I use other HTTP servers
but SocketPro server as a COMET server? If so, how can I do it? |