First, Introduction
Signal is a Microsoft-supported HTML WebSocket framework that runs on the Dot NET platform. The main purpose of this is to implement a server proactive push (push) message to the client page so that the client does not have to resend the request or use polling technology to obtain the message.
Second, the realization mechanism
The implementation mechanism of SignalR is similar to. NET WCF or Remoting, and is implemented using a remote proxy. For specific use, there are two different purposes of interfacing: Persistentconnection and Hubs, where Persistentconnection is a long-time Javascript poll (similar to Comet), the Hub is used to solve the real-time information exchange problem, it is implemented using Javascript dynamic loading execution method. SignalR the entire connection, the information exchange process is very beautiful package, the client and the server side all use JSON to exchange data.
The following is the use of the Hubs interface to tell the whole process:
1, define the corresponding hub class on the server side;
2, the proxy class corresponding to the hub class is defined in the client;
3, establish the connection between client and server (connection);
4, then the client can call the proxy object method to invoke the server-side method, that is, send the request to the server side;
5, after the server receives the request, it can send messages for a/group client or all clients (broadcasts).
Three, Hub sample tutorial
1, tool preparation
SignalR runs on the. NET 4.5 platform, so you need to install. NET 4.5. For demonstration purposes, this example uses ASP. NET MVC in the Win 7 system. This requires the installation of ASP. NET MVC 3 or ASP. 4.
2, set up the project
Open vs2010/vs2012 New ASP. NET MVC 3 Web Application project named Signalrtutorial, select the Internet application template, Razor view engine, and tick the use HT Ml 5 label.
3, install SignalR
Open the Package Manager console for NuGet, input: Install-package signalr.sample, enter Tools->library. :
4, implement the HUB server-side code
Create a new SignalR directory in the project where you add the ChatHub.cs file with the following contents:
Namespace SIGNALTUTORIAL.SIGNALR
{
[Hubname ("chat")]
public class Chat:hub
{
public void Send (string clientName, String message)
{
var toselfinfo = "You had sent message" + message;
Caller.addsomemessage (ClientName, toselfinfo);
Call the AddMessage method on all clients
Clients.addsomemessage (clientName, message);
Clients[context.connectionid].addsomemessage (clientName, data);
}
}
}
In the code above:
1), Hubname This feature is to let the client know how to establish a server-side corresponding service proxy object, if not set this attribute, the server-side service class name as the default value of Hubname;
2), Chat inherits from the hub, from the following hub interface diagram can be seen: The hub support to the initiator (Caller), all clients (clients), a specific set (group) push messages.
3), public void Send (string clientName, String message) This interface is called by the client through the proxy object;
4), clients is the Hub attribute, which represents all linked client pages, and it is dynamic as Caller, as it is directed to the Javascript object;
5), Clients.addsomemessage (clientName, message); Represents the Addsomemessage method of the server-side call client, which is a Javascript method that pushes messages to the client.
6), Summary: The service here is very simple, that is, when a client calls the Send method to send a message to the server, the server is responsible for the message broadcast to all clients (or to specific groups or specific clients, see masking code), in order to implement the function of the chat room.
5, implementing the Hub client code
1), referencing SignalR Javascript
To simplify referencing SignalR script operations, I introduced SignalR and other scripts directly in view/shared/_layout.cshtml:
Note: SignalR relies on jquery, so SignalR must be placed behind jquery, and hubs must be placed after SignalR.
Then add Hubchat Tab in the body section:
@Html. ActionLink ("Hubchat", "Hubchat", "Home")2), Generate access page
Add the following method to the HomeController:
Public ActionResult Hubchat ()
{
Viewbag.clientname = "User-" + rnd.next (10000, 99999);
return View ();
}
Here the server based on the random number to set the client's name, not rigorous, because the random number generated by the name is not unique, here only to simplify the demonstration, the actual application should use the GUID.
Then generate the corresponding View:HubChat.cshtml
@model Dynamic
@{
Viewbag.title = "Title";
}
Hub Chat
Message logging: (You are:@ViewBag. ClientName):
In the above page code, I added a script named Hubdemo.js, which is described below, and there is a hidden input control with ID Placeholder, which is to pass the name of the client to Javascript.
3), write Javascript
Add a new Javescript script to the Scripts directory: Hubdemo.js. The contents are as follows:
$ (function () {
var myclientname = $ (' #Placeholder '). Val ();
Proxy created on the fly
var chat = $.connection.chat;
Declare a function on the chat hub so the server can invoke it
Chat.addsomemessage = function (clientName, message) {
WriteEvent ('+ clientName + ' said to everyone: ' + message, ' event-message ');
};
$ ("#broadcast"). Click (function () {
Call the chat method on the server
Chat.send (Myclientname, $ (' #msg '). Val ())
. Done (function () {
Console.log (' Sent message success! ');
})
. Fail (function (e) {
Console.warn (e);
});
});
Start the connection
$.connection.hub.start ();
A function to write events to the page
function WriteEvent (EventLog, Logclass) {
var now = new Date ();
var nowstr = now.gethours () + ': ' + now.getminutes () + ': ' + now.getseconds ();
$ (' #messages '). Prepend ('
' + nowstr + '' + EventLog + '. ');}
});
The above code has a detailed comment, the following is the key point:
1, first get the name of the client page;
2, then through the $.connection.chat to establish the corresponding server-side Hub class proxy object chat;
3, defines the client's Javascript method Addsomemessage, the server calls the client's method in dynamic mode to implement push functionality. Whenever a message is received from the server, the message is inserted in the messages list header of the client page.
4, when the broadcast button is clicked, the client invokes the server-side send method through the proxy object to implement a message to the server.
5, through $.connection.hub.start (); Statement to open the link.
6), compile run Hub sample
To open a page in multiple browser windows, the effect is as follows:
Four, persistent Connection sample tutorial
1, implement server-side code
1), write the server persistentconnection code
Add the PersistentConnection.cs file to the SignalR directory in the project as follows:
Using System;
Using System.Collections.Generic;
Using System.Threading.Tasks;
Using SignalR;
Namespace SIGNALTUTORIAL.SIGNALR
{
public class Myconnection:persistentconnection
{
protected override Task Onconnectedasync (irequest request, String ConnectionID)
{
Return Connection.broadcast ("Connection" + ConnectionID + "Connected");
}
protected override Task Onreconnectedasync (irequest request, IEnumerable groups, String clientId)
{
Return Connection.broadcast ("Client" + clientId + "re-connected");
}
protected override Task Onreceivedasync (irequest request, String ConnectionID, String data)
{
var info = data + ". ConnectionID is ["+ ConnectionID +"] ";
Return Connection.send (ConnectionID, info);
Broadcast data to all clients
return Connection.broadcast (info);
}
protected override Task Ondisconnectasync (string ConnectionID)
{
Return Connection.broadcast ("Connection" + ConnectionID + "disconncted");
}
protected override Task Onerrorasync (Exception error)
{
Return Connection.broadcast ("error ocurred" + error);
}
}
}
In the code above:
1,myconnection inherits from the Persistentconnection, so that we can handle the processing in the case of client connection, reconnection, disconnection, sending of messages and connection errors. As you can see from the Persistentconnection interface below, Persistentconnection also supports groups for push.
2, the push message is provided by the Persistentconnection property Connection, which inherits from the Iconnection interface, which provides two functions for push and broadcast to a specific client.
System.Threading.Tasks.Task Send (String signal, object value)
System.Threading.Tasks.Task broadcast (object value)
2), configure access routing
In order to support client access, it needs to be configured in the routing table. Open Global.asax.cs and modify the Application_Start () function as follows:
protected void Application_Start ()
{
Arearegistration.registerallareas ();
RouteTable.Routes.MapConnection ("echo", "echo/{*operation}");
Registerglobalfilters (globalfilters.filters);
RegisterRoutes (routetable.routes);
Make connections wait 50s maximum for any response. After
50s is up, trigger a timeout command and make the client reconnect.
GlobalHost.Configuration.ConnectionTimeout = Timespan.fromseconds (50);
Disconnecttimeout
HeartbeatInterval
KeepAlive
}
In the above code, I mapped the access of ECHO and its sub-paths to myconnection and set the connection time-out to. Here you can also set some other parameters, such as the disconnection time-out period, heartbeat interval and so on.
2, implementing client code
1), Generate access page
On the basis of the previous three Hub sample tutorial, we added a demo to the project using persistent Connection. As before, add Persistentchat Tab to _layout.cshtml:
@Html. ActionLink ("Persistentchat", "Persistentchat", "Home")Then add the following method to the HomeController:
Public ActionResult Persistentchat ()
{
Viewbag.clientname = "User-" + rnd.next (10000, 99999);
return View ();
}
Here the server based on the random number to set the client's name, not rigorous, because the random number generated by the name is not unique, here only to simplify the demonstration, the actual application should use the GUID.
Then generate the corresponding page: persistentchat.cshtml:
@model Dynamic
@{
Viewbag.title = "Title";
}
Persistent Chat
Message logging: (You are:@ViewBag. ClientName):
In the above page code, I added a script named Persistent.js, which is described below, and there is a hidden input control with ID Placeholder, which is to pass the name of the client to Javascript.
2), write Javascript
Add a new Javescript script to the Scripts directory: Persistent.js. The contents are as follows:
$ (function () {
var myclientname = $ (' #Placeholder '). Val ();
var connection = $.connection ('/echo ');
Connection.received (function (data) {
var msg = new String (data);
var index = msg.indexof ("#");
var clientName = msg.substring (0, index);
var content = msg.substring (index + 1);
if (ClientName = = NULL | | clientName = = "") {
WriteEvent (' + ' + 'system message ' + ': ' + content, ' event-message ');
}
else {
WriteEvent ('+ clientName + ' said to everyone: ' + content, ' event-message ');
}
});
Connection.start ();
$ ("#broadcast"). Click (function () {
var msg = myclientname + "#" + $ (' #msg '). Val ();
Connection.send (msg);
});
A function to write events to the page
function WriteEvent (EventLog, Logclass) {
var now = new Date ();
var nowstr = now.gethours () + ': ' + now.getminutes () + ': ' + now.getseconds ();
$ (' #messages '). Prepend ('
' + nowstr + ' ' + EventLog + '. ');}
});
The above code is basically the same as the previous HUB implementation, where it is no longer one by one to tell. There are two points worth explaining:
1, when creating the connection, the specified path is "/echo", the path on the server side of the route map table is mapped to myconnection, so this connection is pointed to the myconnection provided earlier.
2, put the ClientName information into the message and use # to concatenate the ClientName and the message content into a single MSG.
3, compiling run persistent example
Using SignalR to implement push functionality in ASP.