Combine WCF, ASP.NET, SignalR for event broadcasting (2)
Posted onDisqus:
Create ASP.NET website with SignalR
From asp.net, SignalR “is a library for ASP.NET developers that simplifies the process of adding real-time web functionality to applications. Real-time web functionality is the ability to have server code push content to connected clients instantly as it becomes available, rather than having the server wait for a client to request new data.” with signalR, it is relatively easy to create a socket between frontend an backend so we can pass data bi-directionally.
Create an empty website (File->New…->Web Site..-> ASP.NET Empty Web Site)
Add SignalR through Nuget. Current version is 2.2.0 and the minimal required .NET framework is 4.5. You can open Nuget Package Manager Console and run Install-Package Microsoft.AspNet.SignalR. This will install all the dependencies.
Start the WCF Service. Use the endpoint from the WCF service (net.tcp://localhost:8733/MyWcfService/), add it as a service Reference.
Add Owin Startup class. Right Click project then Add…-> New Item… -> OWIN Startup class. You can name it Startup.cs. Add app.MapSignalR(); into the function “Configuration” for now.
Add Hub class. Hub class, by the name, is the place that all the clients are connecting to so they can exchange messages. To make sure out hub class can talk with both javascript frontend and WCF backend, we need to derive our class from Hub class and implements our IClientCallback. The full code:
<!--Script references. --> <!--Reference the jQuery library. --> <script src="Scripts/jquery-1.10.2.min.js"></script> <!--Reference the SignalR library. --> <script src="Scripts/jquery.signalR-2.2.0.min.js"></script> <!--Reference the autogenerated SignalR hub script. --> <script src="signalr/hubs"></script> <!--Add script to update the page and send messages.--> <script src="Scripts/broadcast.js"></script> </body> </html>
The actualy jQuery library may vary, double check your Scripts folder and use correct jQuery library.
Add some logic to OWIN Startup class to mimic to following workflow: client first subscribe it to the service log broadcaster, then client explicitly call another service and get updates. Updated Startup.cs will look like this:
public MyWcfServiceClient MyWcfServiceClient { get { if (_mywcfServiceClient == null) { _mywcfServiceClient = new MyWcfServiceClient(DEFAULT_TCP_BINDING_ENDPOINT_NAME); }
public MyWcfServiceAsyncClient MyWcfServiceAsyncClient { get { if (_myWcfServiceAsyncClient == null) { InstanceContext instanceContext = new InstanceContext(StatusUpdateHandlerHub); _myWcfServiceAsyncClient = new MyWcfServiceAsyncClient(instanceContext); }
if (_myWcfServiceAsyncClient.State == CommunicationState.Closed) { _myWcfServiceAsyncClient.Open(); }
return _myWcfServiceAsyncClient; } }
public StatusUpdateHandlerHub StatusUpdateHandlerHub { get { return _statusUpdateHanderHub ?? (_statusUpdateHanderHub = new StatusUpdateHandlerHub()); } }
public void Configuration(IAppBuilder app) {
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888 app.MapSignalR(); MyWcfServiceAsyncClient.ListenToEvents();
MyWcfServiceClient.DoWork();
} }
Add broadcast.js under Scripts with the following content:
1 2 3 4 5 6 7 8 9 10
$(function() { var anaHub = $.connection.statusUpdateHandlerHub; // this is always the class name with the first letter lower case
anaHub.client.listenToStatus = function(message) { $("#statusDiv").html(message); }; $.connection.hub.start().done(function() { anaHub.server.listenToStatus(); // similarly, this is the function name in the hub with the first letter lowered }); });
Explanation: We first get a object of the hub by calling $.connection.{hubname}. Then we add a listenToStatus function to the clients. So we can invoke this from backend Clients.All.listenToStatus(message);
From the client, we also call the server function listenToStatus which is also defined in the Hub class public void ListenToStatus() {...}
Run the program, you should be able to see the ticking time now!