Home  >  Article  >  Backend Development  >  Introduction to SignalR and usage introduction

Introduction to SignalR and usage introduction

零下一度
零下一度Original
2017-06-24 10:45:184062browse

The content shared with you in this chapter is to use the Signal R framework to create a simple group chat function. It mainly explains how to use this framework in .Net's MVC. Since this project has official documents (all in English of course), there will be no details later. I plan to write a sharing article. The main purpose is to let friends have more solutions when they need to use Web real-time communication. After all, this is one of the solutions mainly promoted by Microsoft.

SignalR Online Introduction

ASP.NET SignalR is a library for ASP.NET developers that simplifies the process of adding real-time web functionality to applications. A real-time web feature is a feature where server code can push content to a connected client as soon as it becomes available, rather than having the server wait for the client to request new data.

SignalR of course also provides a very simple and easy-to-use high-level API, which allows the server to call JavaScript functions on the client individually or in batches, and it is very convenient to perform connection management, such as the client connecting to the server. , or disconnection, client grouping, and client authorization are all very easy to implement using SignalR.

SignalR brings real-time communication with clients to ASP .NET. Of course, this is easy to use and has sufficient scalability. In the past, users needed to refresh the page or use Ajax polling to achieve real-time display of data. Now they can simply use SignalR. The most important thing is that you don't need to re-create the project, you can use SignalR seamlessly using your existing ASP .NET project.

Group chat instance effect

Let’s take a look at the effect of the test case first. Here is the online effect link: 神牛 Chat Room(:1001/home /shenniuchat), rendering:

##The interface is extremely simple, the style will not be considered here, the main purpose is to show its usage, the functions involved here are:

1. Count the number of online people

2. Display the nickname and connection method of the online people (this test case supports webSockets and longPolling (long connection))

3. Group chat information

How to use SignalR in MVC

First, we usually create an MVC Web project, and then use the Nuget console command:

Install-package Microsoft.AspNet.SignalR Add SignalR Dependencies, the automatically added packages are as follows:

  <package id="Microsoft.AspNet.SignalR" version="2.2.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.SignalR.Core" version="2.2.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.SignalR.JS" version="2.2.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.SignalR.SystemWeb" version="2.2.2" targetFramework="net45" />
and automatically add related js files to the Script folder in the MVC project:

jquery.signalR-2.2.2.min.js
jquery.signalR-2.2.2.js
Then, we need to create a class with the file name Startup.cs in the project first-level directory, and the main content in it cannot be completed:

 1 [assembly: OwinStartup(typeof(Stage.Api.Extend.Startup))] 2 namespace Stage.Api.Extend 3 { 4     public class Startup 5     { 6         public void Configuration(IAppBuilder app) 7         { 8             app.MapSignalR("/chat", new Microsoft.AspNet.SignalR.HubConfiguration 9             {10                 EnableDetailedErrors = true,11                 EnableJavaScriptProxies = true12             });13         }14     }15 }
First we analyze and pay attention from top to bottom. Point:

1.

OwinStartup(Type) The constructor passes a type, and this type corresponds to the Startup class we created. This constructor class marks the starting position. ;

2.

namespace Stage.Api.Extend is the namespace of my project, this can be defined at will;

3.

public void Configuration(IAppBuilder app) The function is fixed and necessary. The program here will first enter this method to execute the logic code inside;

4.

app.MapSignalR is an extended IAppBuilder interface method. It has many forms of expression. Here I choose public static IAppBuilder MapSignalR( this IAppBuilder builder, string path, HubConfiguration configuration);, here it looks a bit similar to our MVC routing. The main thing to note here is the Path parameter, which is needed on the front-end page. Use this path;

The configuration required in the background has actually been completed here. The following is the specific operation required

Business logic processing class, create a new class (here I named itChatHub) and inherits Hub (which is provided by the SignalR framework), and the logic code inside is as follows:

 1 public class ChatHub : Hub 2     { 3         // 4         public int Num = 10001; 5         public static List<MoHubUser> _Users = new List<MoHubUser>(); 6  7         /// <summary> 8         /// 添加聊天人 9         /// </summary>10         /// <param name="user"></param>11         public void AddUser(MoHubUser user)12         {13 14             user.Id = Context.ConnectionId;15             if (!_Users.Any(b => b.Id == user.Id))16             {17                 _Users.Add(user);18             }19 20             //Clients.All.newUser(user);21             Clients.All.userList(_Users);22         }23 24         /// <summary>25         /// 发送信息26         /// </summary>27         /// <param name="user"></param>28         /// <param name="message"></param>29         public void SendAll(MoHubUser user, string message)30         {31             Clients.All.addNewMessageToPage(user, message);32         }33 34         /// <summary>35         /// 某个聊天人退出是,通知所有在线人重新加载聊天人数36         /// </summary>37         /// <param name="stopCalled"></param>38         /// <returns></returns>39         public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled)40         {41             var user = _Users.SingleOrDefault(x => x.Id == Context.ConnectionId);42             if (user != null)43             {44                 _Users.Remove(user);45                 Clients.All.userList(_Users);46             }47             return base.OnDisconnected(stopCalled);48         }49     }

上面的3个方法分别做了:添加聊天人到List,发送信息到客户端,某个连接失效后通知各个有效的聊天人重新加载信息;这里值得关注的是通过重新 public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled) 方法来实现捕获并移除失效连接(这里是聊天人的信息);整篇测试用例通过Context.ConnectionId来保证连接的唯一性,只要有新的链接请求,那么服务端就会分配一个唯一串给这个链接,当客户端关闭页面或关闭链接这个是有就能在OnDisconnected方法中捕获到这个失效的链接的ConnectionId,这样就达到了移除失效聊天人的要求了;为了代码的方便性,这里创建了一个聊天人信息类:

1  public class MoHubUser2     {3 4         public string Id { get; set; }5         public string NickName { get; set; }6         public string TransportMethod { get; set; }7     }

到这里后台的聊天室代码就完成了就是这么简单;我们再来看试图中如何来写代码,这里我先给出我的html布局代码:

 1 @{ 2     ViewBag.Title = "神牛聊天室 - SignalR"; 3 } 4 <style type="text/css"> 5     .div_left { 6         width: 70%; 7         float: left; 8     } 9 10     .div_right {11         width: 28%;12         float: left;13     }14 15     .ul {16         list-style: none;17         border: 1px solid #ccc;18         height: 500px;19         overflow-y: scroll;20         color: black;21     }22 23         .ul li {24             padding-top: 5px;25             padding-right: 25px;26         }27 28     .ul_user {29         list-style: none;30     }31 32         .ul_user li {33             padding-top: 5px;34         }35 36     .send {37         position: relative;38         background: #eae7e7;39         border-radius: 5px; /* 圆角 */40         padding-top: 4px;41         padding-left: 5px;42         margin-top: 13px;43     }44 45         .send .arrow {46             position: absolute;47             top: -16px;48             font-size: 0;49             border: solid 8px;50             border-color: #fff #fff #eae7e7 #fff;51         }52 </style>53 <h3>@ViewBag.Title 在线人数:<span id="sapnUserTotal">0</span>人</h3>54 <div class="container text-left">55     <div class="div_left">56         <ul class="ul" id="discussion"></ul>57         <textarea rows="5" class="form-control" id="message" maxlength="500" placeholder="开始聊天. . ." style="max-width: 100%"></textarea><br />58         <input type="button" id="sendmessage" value="发 送" class="btn btn-default" />59         <input type="hidden" id="displayname" />60     </div>61     <div class="div_right">62         <ul id="users" class="ul_user"></ul>63     </div>64 </div>65 66 <script src="~/Scripts/jquery.signalR-2.2.2.min.js"></script>67 @*<script src="~/chat/hubs"></script>*@

客户端这里写法大致有两种选择,一种直接使用生成的代理来操作,一种不用自动生成的代理采用手动创建代理的方式;为了内容的简洁性,这里只简单讲解下自动生成的代理方式,而更多的是分享手动创建代理链接的方式;

使用生成的代理获取链接

首先,我们需要通过Script标签来引用一下自动生成代理的路径:  ,注意啦这里的路径/chat对应的就是咋们在前面Startup.cs文件中配置 app.MapSignalR("/chat" 路径,而后面/hubs固定的写法(至少目前我还没更多的试验过),只有先应用了这个~/chat/hubs,才能在后面使用生成的代理,先上段代码:

 1  var chat = $.connection.chatHub; 2         chat.client.newUser = function (user) { 3             $("#users").append(' <li><strong>' + user.NickName + '[' + user.TransportMethod + ']</strong></li>'); 4         }; 5  6         chat.client.userList = function (users) { 7             console.log(users); 8             $("#sapnUserTotal").html(users.length); 9             $.each(users, function (i, item) {10                 $("#users").append(' <li>[' + item.TransportMethod + '] <strong>' + item.NickName + '</strong>(' + item.Id + ')</li>');11             });12         };13         chat.client.addNewMessageToPage = function (user, message) {14             console.log(user);15             $("#discussion").append(' <li ><span><strong>' + user.NickName + '[' + user.TransportMethod + ']</strong>:</span><div class="send">' + message + '<div class="arrow"></div></div></li>');16         };17    //connection.hub.start({ transport: ['webSockets', 'longPolling'] }).done(function () {18         //    my.TransportMethod = connection.hub.transport.name;19         //    chat.server.addUser(my);20 21         //    $('#sendmessage').click(function () {22         //        //console.log(chat);23         //        var content = $.trim($('#message').val());24         //        if (content.length <= 0) { $('#message').val('').focus(); return; }25         //        chat.server.sendAll(my, content);26         //        $('#message').val('').focus();27         //    });28         //}).fail(function () {29         //    alert("链接聊天室失败,请重新刷新页面。");30         //});

咋们逐步来解析下代码注意点:

1.  var chat = $.connection.chatHub; 这里的chatHub对应的就是咋们创建的并继承Hub的ChatHub类,由于js变量开头都是小写,所以这里是chatHub,这句活就表示链接到咋们后端了ChatHub类了,然后就可以使用里面的方法啦(这种有点类似于早期的webform中某种ajax请求的写法)

2. 通过chat.client.xxx来接收服务端通知的消息,而这个xxx对应的方法名称和咋们后端的Clients.All.xxx,本章实例对应的是:chat.client.userList = function (users){}对应Clients.All.userList(_Users);这样后端就能直接通知客户端的对应方法了;注意这里我后端Clients.All用的是通知全部客户端的意思,如果您需要通知指定的链接需要用到的是: T Client(string connectionId); 方法

3. chat.client是后端调用客户端,那相对的chat.server就是客户端请求服务端,和上面一样通过chat.server.xxx来指定请求的服务端方法,注意这个时候服务端方法指的是继承类Hub的子类的公共方法(本篇对应的是:chat.server.sendAll(my, content)对应ChatHub.cs文件中的 public void SendAll(MoHubUser user, string message) 函数)

4.  connection.hub.start({ transport: ['webSockets', 'longPolling'] }) 来指定运行的交互协议

以上就是使用生成代理的方式,按照上面的注意点来写应该不是问题;

使用手动创建反向代理来链接

不采用生成的代码的方式,我们只需要修改前端就行了,后台代码不用变或设置不用变动;首先我们把上面说的Script引用自动代理的代码去掉,因为这个时候不需要了,我们还是先上代码:

 1 var my = { NickName: "神牛001", TransportMethod: "" }; 2         var connection = $.hubConnection("/chat/hubs"); 3         var chat = connection.createHubProxy('chatHub'); 4  5         chat.on("userList", function (users) { 6             console.log(users); 7             $("#sapnUserTotal").html(users.length); 8             $("#users").html(""); 9             $.each(users, function (i, item) {10                 $("#users").append(' <li>[' + item.TransportMethod + '] <strong>' + item.NickName + '</strong>(' + item.Id + ')</li>');11             });12         });13 14         chat.on("addNewMessageToPage", function (user, message) {15             console.log(user);16             $("#discussion").append(' <li ><span><strong>' + user.NickName + '[' + user.TransportMethod + ']</strong>:</span><div class="send">' + message + '<div class="arrow"></div></div></li>');17 18             var div = document.getElementById('discussion');19             //div.scrollTop = div.scrollHeight;20             div.scrollTop = 999999;21         });22 23         var nickName = prompt("请输入一个昵称:", my.NickName);24         my.NickName = nickName.length > 0 ? nickName : my.NickName;25         $('#displayname').val(nickName);26         $('#message').focus();27      28 29         connection.start({ transport: ['webSockets', 'longPolling'] }).done(function () {30 31             my.TransportMethod = connection.transport.name;32             //console.log(my.TransportMethod);33             chat.invoke("addUser", my);34 35             $('#sendmessage').click(function () {36                 var content = $.trim($('#message').val());37                 if (content.length <= 0) { $('#message').val('').focus(); return; }38 39                 chat.invoke("sendAll", my, content);40                 $('#message').val('').focus();41             });42         });

The following points are also listed:

1. var connection = $.hubConnection("/chat/hubs"); Create a link, the path here also corresponds to the backend app.MapSignalR("/chat" , the path remains consistent

2. var chat = connection.createHubProxy('chatHub '); To create a reverse proxy link, the name here: chatHub corresponds to the back-end ChatHub class name

3. Through on("xxx", function(){}) Function to bind the event that the server notifies the client, xxx corresponds to xxx

4 in Clients.All.xxx. connection.start({ transport: [' webSockets', 'longPolling'] }) to set the allowed link method and start linking

5. connection.transport.name to get the name of the link method. If start is not set by default, there are several types: webSockets, foreverFrame, serverSentEvents, longPolling

6. chat.invoke("xxx ", param1, param2) uses invoke to map the public methods of classes that inherit class Hub. The instance here corresponds to: chat.invoke("sendAll" , my, content) corresponds to public void SendAll(MoHubUser user, string message)

Write at the end

If the above points are met, then the basic SignalR can be linked and used successfully. There are many points to note, but they are just summarized experiences. I hope many friends can help; I am writing this article. At that time, a friend happened to be looking at my git open source LovePicture.Web project. It was said that they would also start to try to use Netcore to build applications in the company. I felt honored and happy for this. It was an honor to be able to contribute to my project. As an example, I am happy that NetCore is becoming more and more influential haha; if you think this article is good or has gained something for you, you might as well recommend, thank you! ! !

The above is the detailed content of Introduction to SignalR and usage introduction. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn