Posts Tagged ‘Asynchronous’
SignalR – Real time pushing of data to connected clients
Updated post about how to create a chat application using SignalR 2.1
How many times you might have refreshed your browser to see the updated score of a cricket match or refresh to get the updated stock details. Isn’t that cool if the browser can display the updated data without refreshing or doing a page load. Yes it is, then the next question come to mind is how to implement it using .NET technology. There is no straight forward approach, most of them have loads of code.
So how do we achieve it? The answer is SignalR. Scott Hanselman have a nice post about SignalR. In his post he explains a small chat application using 12 lines of code.
I wanted a real time pushing of data to ASP.NET, Javascript client or desktop clients for a project I am working on. The details of that project I will post it later. I am aware of SignalR but never really tried or doesn’t know how to make it work. Yesterday I decided to write a tracer to better understand how SignalR works. This post is all about that tracer I created.
Tracer Functionality
The functionality is very simple. I need two clients a console and a web app. Data entered in any of these clients should reflect in other one. A simple functionality to test SignalR.
Let’s go through the implementation.
I have three projects in my solution 1. SignalR self hosted server 2. A console Client 3. A Web application.
SignalR server
Here I used a self hosting option. That means I can host the server in Console or Windows service. Have a look at the code.
using System; using System.Threading.Tasks; using SignalR.Hosting.Self; using SignalR.Hubs; namespace Net.SignalR.SelfHost { class Program { static void Main(string[] args) { string url = "http://localhost:8081/"; var server = new Server(url); server.MapHubs(); server.Start(); Console.WriteLine("SignalR server started at " + url); while (true) { ConsoleKeyInfo ki = Console.ReadKey(true); if (ki.Key == ConsoleKey.X) { break; } } } public class CollectionHub : Hub { public void Subscribe(string groupName) { Groups.Add(Context.ConnectionId, groupName); Console.WriteLine("Subscribed to: " + collectionName); } public Task Unsubscribe(string groupName) { return Clients[groupName].leave(Context.ConnectionId); } public void Publish(string message, string groupName) { Clients[groupName].flush("SignalR Processed: " + message); } } } }
As you can see from the main I hosted the SignalR server in a specific URL. You can see another Class called CollectionHub inherited from Hub. So what is a hub? Hubs provide a higher level RPC framework, client can call the public functions declared in the hub. In the above Hub I declared Subscriber, Unsubscribe and Publish function. The clients can subscribe to messages by providing a Collection Name, it’s like joining to a chat room. Only the members in that group receives all the messages.
You will notice another function called Publish with a message and a groupName. The clients can call the publish method by passing a message and a group name. SignalR will notify all the clients subscribed to that group with the Message passed. So what’s this ‘flush’ function called in publish, it’s nothing but the function defined in the client. We will see that later.
We are done, run the console application and our SignalR server is ready to receive requests.
SignalR clients
First we will look into a Console client. Let’s see the code first.
using SignalR.Client.Hubs; namespace Net.SignalR.Console.Client { class Program { static void Main(string[] args) { var hubConnection = new HubConnection("http://localhost:8081/"); var serverHub = hubConnection.CreateProxy("CollectionHub"); serverHub.On("flush", message => System.Console.WriteLine(message)); hubConnection.Start().Wait(); serverHub.Invoke("Subscribe", "Product"); string line = null; while ((line = System.Console.ReadLine()) != null) { // Send a message to the server serverHub.Invoke("Publish", line, "Product").Wait(); } System.Console.Read(); } } }
Let’s go line by line.
-
Create a hub connection with the url where SignalR server is listening.
-
Create a proxy class to call functions in CollectionHub we created in the server.
-
Register an event and callback, so that Server can call client and notify updates. As you can the Event name is ’Flush’, if you remember the server calls this function in Publish function to update the message to clients.
-
Start the Hub and wait to finish the connection.
-
We can call any public method in declared in Hub using the Invoke method by passing the function name and arguments.
Run the console application and type anything and hit enter. You can see some thing like below.
The name prefixed ‘SignalR Processed’ is the message back from the SignalR server. So we are done with a console application.
Now how about we have to display the updates in a web application. Let’s see how to do it in web application. In web application I used javascript to connect to the SignalR server.
<html xmlns="http://www.w3.org/1999/xhtml"> <script src ="Scripts/json2.js" type="text/jscript"></script> <script src="Scripts/jquery-1.6.4.min.js" type="text/javascript"></script> <script src="Scripts/jquery.signalR-0.5.3.min.js" type="text/javascript"></script> <script type="text/javascript"> $(function () { var connection = $.hubConnection('http://localhost:8081/'); proxy = connection.createProxy('collectionhub') connection.start() .done(function () { proxy.invoke('subscribe', 'Product'); $('#messages').append('<li>invoked subscribe</li>'); }) .fail(function () { alert("Could not Connect!"); }); proxy.on('flush', function (msg) { $('#messages').append('<li>' + msg + '</li>'); }); $("#broadcast").click(function () { proxy.invoke('Publish', $("#dataToSend").val(), 'Product'); }); }); </script> <body> <div> <ul id="messages"></ul> <input type="text" id="dataToSend" /> <input id="broadcast" type="button" value="Send"/> </div> </body> </html>
You can install SignalR Javascript client from Nuget and it will install all the required js files. The code looks very similar to the one in Console application. So not explaining in detail.
Now if you run all three application together and any update in one client will reflect in other. As you can see in web client we use Javascript for DOM manipulation, so the page will never refresh but you will see the updated info.
I hope this post might help you to get started with SignalR.
Dowload the source code.
Happy coding….
Multi client Asynchronous TCP Server
This post is based on a tracer I am currently working on. My current project requires a TCP server implementation where other client could establish communication and perform data processing. The server should be able to handle multiple request from client. I never did any work with TCP Listener, initial one hour struggled a lot to get it working.
First approach I took was kind of Server – Server communication. That means there is no client both system act as server, it’s bit complex but I created a working prototype in next couple of hours. Yes it is complex, client app needs lot of work to establish a connection.
I need the server more simple and less code for the client to establish connection. So I started searching for simple TCP based client server approach. I stumble upon this post, where the author does a multi client communication. I got a start for my second tracer, a true client server model. I modified it and removed looping construct and used Async model instead. You all can see the code below.
TCP Server
private static TcpListener _listener; public static void StartServer() { System.Net.IPAddress localIPAddress = System.Net.IPAddress.Parse("10.91.173.201"); IPEndPoint ipLocal = new IPEndPoint(localIPAddress, 8888); _listener = new TcpListener(ipLocal); _listener.Start(); WaitForClientConnect(); } private static void WaitForClientConnect() { object obj = new object(); _listener.BeginAcceptTcpClient(new System.AsyncCallback(OnClientConnect), obj); } private static void OnClientConnect(IAsyncResult asyn) { try { TcpClient clientSocket = default(TcpClient); clientSocket = _listener.EndAcceptTcpClient(asyn); HandleClientRequest clientReq = new HandleClientRequest(clientSocket); clientReq.StartClient(); } catch (Exception se) { throw; } WaitForClientConnect(); } }
Here I use a async wait approach rather than waiting in a loop. So whenever a client connect OnClientConnected will fire and it handover the request to Client Request handler. After that it will again go back to wait mode for the next request. The advantage of this approach, the application is responsive and less CPU intensive compare to the looping approach.
Let’s see the client request handler
public class HandleClientRequest { TcpClient _clientSocket; NetworkStream _networkStream = null; public HandleClientRequest(TcpClient clientConnected) { this._clientSocket = clientConnected; } public void StartClient() { _networkStream = _clientSocket.GetStream(); WaitForRequest(); } public void WaitForRequest() { byte[] buffer = new byte[_clientSocket.ReceiveBufferSize]; _networkStream.BeginRead(buffer, 0, buffer.Length, ReadCallback, buffer); } private void ReadCallback(IAsyncResult result) { NetworkStream networkStream = _clientSocket.GetStream(); try { int read = networkStream.EndRead(result); if (read == 0) { _networkStream.Close(); _clientSocket.Close(); return; } byte[] buffer = result.AsyncState as byte[]; string data = Encoding.Default.GetString(buffer, 0, read); //do the job with the data here //send the data back to client. Byte[] sendBytes = Encoding.ASCII.GetBytes("Processed " + data); networkStream.Write(sendBytes, 0, sendBytes.Length); networkStream.Flush(); } catch (Exception ex) { throw; } this.WaitForRequest(); }
}
Here also I converted the waiting in loop to Async wait model. The looping model causes a constant hike in CPU utilization. This post explain how to asynchronously read request from client.
That’s all the server side. The client side is shown below
public class TCPClient { System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient(); NetworkStream serverStream; public void ConnectToServer() { clientSocket.Connect("10.91.173.201", 8888); } public void SendData(string dataTosend) { if (string.IsNullOrEmpty(dataTosend)) return; NetworkStream serverStream = clientSocket.GetStream(); byte[] outStream = System.Text.Encoding.ASCII.GetBytes(dataTosend); serverStream.Write(outStream, 0, outStream.Length); serverStream.Flush(); } public void CloseConnection() { clientSocket.Close(); }
public string ReceiveData() { StringBuilder message = new StringBuilder(); NetworkStream serverStream = clientSocket.GetStream(); serverStream.ReadTimeout = 100; //the loop should continue until no dataavailable to read and message string is filled. //if data is not available and message is empty then the loop should continue, until //data is available and message is filled. while (true) { if (serverStream.DataAvailable) { int read = serverStream.ReadByte(); if (read > 0) message.Append((char)read); else break; } else if (message.ToString().Length > 0) break; } return message.ToString(); } }
As you can see most of the function is very simple to understand except ReceiveData(). I haven’t concentrated much on the client side as client of the actual TCP server will not be a .NET one. I am not discarding the fact, I will refactor ReceiveData().
Making Async calls in Silverlight using Reactive Extension (Rx)
In this blog I am going to explain briefly about how to make async calls using Reactive Extension (Rx). Every one knows that Silverlight is one of the best platform to create RIA’s. One of the architecture constrain of Silverlight is, it wont directly interact with backend DB. So we need to have a webservice to perform the db operations. Silverlight can consume WCF or asmx service, but their is a catch silverlight can only communicate to webservices asynchronously. We all know that async calls have several advantages. One key feature of async call is, it wont block the UI while performing the call. But one downside in async programming is the coding pattern involved in placing async calls. When I place an async calls, I use an anonymous delegate approach or use lambda expression. But some how I am not satisfied with any of these approaches, I feel my code is not clean. So we always look for a better approach and our long waiting is over with the introduction of Reactive Extension (Rx) from MS labs.
You can visit Rx web site to get more details. I am not a person to explain the architecture or indepth details of Rx instead I am going to show how it benefit me in my async programing. I am going to rewrite one of my application I wrote to upload images using Silverlight and WCF, you can get more details of that app from my blog. I will rewrite only the part where I make async calls to server to get images from WCF service. Before get into refactoring, We need to download and install the Rx libraries from Rx web site.
Let’s refactor the code to make our async calls using Rx. We need to add couple of assembly references to add Rx to Silverlight, below are those assemblies.
- System.Observables
- System.CoreEx
- System.Reactive
I demonstrated two ways of interacting with WCF service in the source code I uploaded. A proxy and proxy less approach. We all know the proxy approach, the communication to the service using the class generated by VS. In one of my post I provided some insight of Proxy less approach, you can check it out here.
If you have my source code in hand, have a look at the ImageListViewModel.cs in Silverlight app. You can see how I am making the async call.
In proxy less approach I use lambda expression to make the call.
IImageServiceAsync imgService = ServiceChannelProvider.CreateChannel<IImageServiceAsync>(); imgService.BeginGetAllImage(save => { try { imgs = imgService.EndGetAllImage(save); this.AddToUserLogoList(imgs); } catch (Exception ex) { throw; } }, imgService);
In proxy approach I used a event driven approach as shown below.
ImageServiceClient imgClient = new ImageServiceClient(); imgClient.GetAllImageCompleted += new EventHandler<GetAllImageCompletedEventArgs>(imgClient_GetAllImageCompleted); imgClient.GetAllImageAsync();
void imgClient_GetAllImageCompleted(object sender, GetAllImageCompletedEventArgs e) { for (int i = 0; i < e.Result.Length; i++) { this.UserLogos.Add(e.Result[i]); } NotifyOfPropertyChange(() => UserLogos); }
I am not going to explain the downside of these approaches mentioned above, Just like me you all might have experienced it. Lets rewrite the code using Reactive Extension (Rx).
Proxy less approach
private void ReadAllImages() { IImageServiceAsync imgService = ServiceChannelProvider.CreateChannel<IImageServiceAsync>(); var func = Observable.FromAsyncPattern<IList<UserImage>>(imgService.BeginGetAllImage, imgService.EndGetAllImage) .Invoke() .SubscribeOnDispatcher() .Subscribe(s => this.UserLogos = s.ToList<UserImage>()); }
Rx have one method called FromAsyncPattern, there we can provide our Beginxxx and Endxxx functions. I provided BeginGetAllImages and EndGetAllImages to FromAsyncPattern function. I also provided the return type of EndGetAllImages() to FromAsyncPattern function. Return type of EndGetAllImages is IList<UserImage>, so I called FromAsyncPattern as FromAsyncPattern<IList<UserImage>>. Rx uses Observer pattern to publish the result. So here I added UserLogos properties as my observer, once the execution is done the result will be pushed to the observer. Here the observer is a property in my view model. Below is the UserLogos property
List<UserImage> _logos = new List<UserImage>(); public List<UserImage> UserLogos { get { return _logos; } private set { lock (this) { _logos = value; NotifyOfPropertyChange(() => UserLogos); } } }
Let’s see how we can make an async call in proxy generated approach.
private void ReadAllImages() { ImageServiceClient imgClient = new ImageServiceClient(); var o = Observable.FromEvent<GetAllImageCompletedEventArgs>(imgClient, "GetAllImageCompleted") .ObserveOn(Scheduler.ThreadPool) .Select(result => result.EventArgs.Result) .Subscribe(s => this.UserLogos = s.ToList<UserImage>()); imgClient.GetAllImageAsync(); }
Here I used FromEvent function provided by Rx instead of FromAsyncPattern. FromEvent accepts the event type, here it is GetAllImageCompletedEventArgs. It also accepts the service client object and which event it should handle. I passed the GetAllImageCompleted to the FromEvent function. Then we need to attach UserLogos as observer. After that we called GetAllImageAsync of service proxy.
You can see our code is pretty clean, we don’t have any messy code that we normally write to handle the async calls. Once you start using Rx I think you will never go back to the old approach of placing async calls.