Asp.net通过SignalR2进行实时聊天
目录
- 一:什么是signalR
- 1、SignalR传输方式
- 1、HTML5 传输
- 2、Comet 传输
- 2、SignalR连接模式
- 二、服务端
- 1、添加服务端Hub
- 2、添加OWIN 启动类
- 三、客户端
- 四、运行结果
- 五、一对一聊天实例
一:什么是signalR Asp.net SignalR是微软为实现实时通信的一个类库。
一般情况下,signalR会使用JavaScript的长轮询(long polling)的方式来实现客户端和服务器通信,随着Html5中WebSockets出现,SignalR也支持WebSockets通信。
另外SignalR开发的程序不仅仅限制于宿主在IIS中,也可以宿主在任何应用程序,包括控制台,客户端程序和Windows服务等,另外还支持Mono,这意味着它可以实现跨平台部署在Linux环境下。
SignalR将整个信息的交换封装起来,客户端和服务器都是使用JSON来沟通的,在服务端声明的所有Hub信息,都会生成JavaScript输出到客户端,.NET则依赖Proxy来生成代理对象,而Proxy的内部则是将JSON转换成对象。
客户端和服务端的具体交互情况如下图所示:
文章图片
1、SignalR传输方式
1、HTML5 传输 这种传输方式当然是需要对HTML5兼容支持。如果客户端不支持HTML5 标准,那么你可以使用其他方式。
- WebSocket: (前提是服务器和客户端都可以支持WebSocket )。WebSocket 是唯一的能够支持服务器和客户端建立真正持久的双向连接的传输方式,但是就是WebSocket要求的条件比较苛刻。
WebSocket真正能够支持只是在最新的IE 浏览器、Chrome、Firefox和一些其他的浏览器比如Opera 和 Safari。 - Server Sent Events (SSE)服务端发送事件 :就是我们常说的EventSource (除了IE的其他浏览器都支持支持服务器发送事件)。
2、Comet 传输 下面的传输方式都是建立在Comet Web应用模型上。这种传输方式会在浏览器或者其他客户端保持一个长连接的HTTP请求,服务器可以利用这个请求将数据推送到客户端,而不用等客户端单独去请求数据。
- Forever Frame:(只有IE浏览器支持)Forever Frame 会创建一个隐藏的IFrame ,这个IFrame 会向服务器发起一个端点请求,但是这个请求不会结束。服务器会不停的发送脚本到客户端马上执行,提供一个从服务器端到客户端的单向实时连接。服务端到客户端和客户端到服务端分别是两个不同的连接,就像一个标准的HTTP请求,一旦有数据需要发送就会创建一个新的连接。
- Ajax Long Polling长轮询:长轮询不会创建一个持久的连接,它是会保持一个客户端与服务器的连接,直到服务器做出应答就会立即关闭,然后创建一个新的连接。当连接重置的时候这会导致一些延迟。
2、SignalR连接模式
- Http Persisten Connection(持久连接)对象:用来解决长时间连接的功能。
还可以由客户端主动向服务器要求数据,而服务器端不需要实现太多细节,只需要处理PersistentConnection 内所提供的五个事件:OnConnected, OnReconnected, OnReceived, OnError 和 OnDisconnect 即可。 - Hub(集线器)对象:用来解决实时(realtime)信息交换的功能,服务端可以利用URL来注册一个或多个Hub,只要连接到这个Hub,就能与所有的客户端共享发送到服务器上的信息,同时服务端可以调用客户端的脚本。
SignalR将整个信息的交换封装起来,客户端和服务器都是使用JSON来沟通的,在服务端声明的所有Hub信息,都会生成JavaScript输出到客户端,.NET则依赖Proxy来生成代理对象,而Proxy的内部则是将JSON转换成对象。
文章图片
二、服务端 原文参考:教程:通过 SignalR 2 进行实时聊天
使用vs2012创建一个新的ASP.NET Web Application项目。
文章图片
1、添加服务端Hub
在解决方案中添加SignalR Hub类选项,然后创建文件ChatHub.cs。此步骤将创建ChatHub.cs类文件并添加一组脚本文件和 SignalR 支持到项目的程序集引用。
注意:可以使用NuGet命令
install-package Microsoft.AspNet.SignalR
来引用SignalR到项目中文章图片
然后在ChatHub类中输入下面这段代码。
using Microsoft.AspNet.SignalR; namespace WebApplication2{public class ChatHub : Hub{//定义可以被网页脚本访问的公共方法public void Send(string name, string message) //在客户端可以使用hub.server.send()方法调用。{// 客户端通过调用broadcastMessage来获取服务端数据Clients.All.broadcastMessage(name, message); //在客户端通过hub.client.broadcastMessage=function(){…}定义这个回调函数。}}}
在ChatHub类中,可以看到它继承自Microsoft.AspNet.SignalR.Hub类。从Hub类派生出类是构建SignalR应用程序的有用方式。在这个类(ChatHub)中定义的公共方法可以被网页内的脚本访问。
在这段代码中(ChatHub类),客户端通过调用ChatHub.Send方法,并把名称和消息内容做为参数传递给ChatHub。而ChatHub则通过Clients.All.broadcastMessage方法把该消息广播给所有客户端。
Send方法演示了几个Hub概念:
- 在hub上声明一些公共方法,以便客户端可以调用它们。
- 使用Microsoft.AspNet.SignalR.Hub。客户端动态属性用于与连接到此中心的所有客户端进行通信。
- 调用客户机上的函数(如broadcastMessage函数)来更新客户机。
2、添加OWIN 启动类
在Solution Explorer中,右击项目,然后添加一个名为Startup的OWIN 启动类,然后输入下面这段代码。
using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(WebApplication2.Startup))]namespace WebApplication2{public class Startup{public void Configuration(IAppBuilder app){app.MapSignalR(); }}}
三、客户端 在项目中添加一个静态网页文件,并命名为index.html,然后右击该网页文件,并选择Set As Start Page,在Index.html中输入下面的代码,注意引用正确的文件名。
SignalR Simple Chat - 锐客网 .container {background-color: #99CCFF; border: thick solid #808080; padding: 20px; margin: 20px; }Reference the jQuery library. Reference the SignalR library. Reference the autogenerated SignalR hub script. Add script to update the page and send messages.
客户端通过jquery.signalR.js和signalr/hubs来与服务器进行通信,首先它要声明一个代理来引用集线器。
var chat = $.connection.chatHub
请注意:在JavaScript中,对服务器类及其成员的引用必须是camelCase形式。本例中将C#服务端的ChatHub类在JavaScript中的引用为chatHub。然后它要再定义一个回调函数,这个回调函数主要是为了让服务器进行调用,从而将数据推送到客户端。
chat.client.broadcastMessage = function (name, message) {//TODO:接收服务器推送的消息};
而下面的代码则是为了确保在将消息发送到服务器之前已经与服务器建立了连接。.done 函数表示连接成功后为发送的按钮绑定一个单击事件。
// 与服务器建立连接后才能发送消息到服务器$.connection.hub.start().done(function () {$('#sendmessage').click(function () {// 调用服务器端的ChatHub.Send方法,把消息发送到服务器chat.server.send("name", "message"); }); });
保存项目,并按F5运行,就可以实现B/S模式下的即时通讯。
四、运行结果 项目运行起来后,同时用多个浏览器打开的,输入各自的姓名之后,就能够实现即时通讯了。回到我们的vs,还能够看到自动生成的hubs脚本文件,如下图所示。
文章图片
文章图片
三个不同的浏览器中的运行方式。 当 Tom、 Anand 和 Susan 发送消息时,所有浏览器实时更新:
文章图片
在ServerHub重写一个 OnConnected 方法来监控客户端的连接情况,程序运行的时候web页面就使用$.connection.hub.start() 与signalR服务开始建立连接了,在调试的时候可以在输入中看到 "客户端连接成功!"
public override Task OnConnected(){System.Diagnostics.Trace.WriteLine("客户端连接成功!"); return base.OnConnected(); }
文章图片
五、一对一聊天实例 【Asp.net通过SignalR2进行实时聊天】Clients.Client(connectionId).addMessage() 此方法的作用就是客户端注册addMessage方法,向指定连接Id的客户端发送消息。一对一的聊天发送的消息也必须回发给自己,所以连接的Id可以通过Context.ConnectionId来获取。当然不用Client.Client(Context.ConnectionId) ,也可以使用Client.Caller()方法直接发送。
Client.Clients(IList connectionIds) 这个方法的意思就是想一组string 的几个ConnectionId发送消息。类似于QQ上@好友的那种功能。
using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Hubs; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; namespace WebApplication2{[HubName("UserHub")]public class UserHub : Hub{#region 字段public static List users = new List(); #endregion 字段#region 方法//获取所有用户在线列表private void GetUsers(){var list = users.Select(s => new { s.Name, s.ConnectionID }).ToList(); string jsonList = JsonConvert.SerializeObject(list); Clients.All.getUsers(jsonList); }//登记名字public void LoginIn(string name){//查询用户var user = users.SingleOrDefault(u => u.ConnectionID == Context.ConnectionId); if (user != null){user.Name = name; //登记名字Clients.Client(Context.ConnectionId).showId(Context.ConnectionId); }GetUsers(); }//发送消息[HubMethodName("sendMessage")]public void SendMessage(string connectionId, string message){Clients.All.hello(); var user = users.Where(s => s.ConnectionID == connectionId).FirstOrDefault(); if (user != null){Clients.Client(connectionId).addMessage(message + "" + DateTime.Now, Context.ConnectionId); //给自己发送,把用户的ID传给自己Clients.Client(Context.ConnectionId).addMessage(message + "" + DateTime.Now, connectionId); }else{Clients.Client(Context.ConnectionId).showMessage("该用户已离线"); }}/// /// 重写连接事件/// /// public override Task OnConnected(){//查询用户var user = users.Where(w => w.ConnectionID == Context.ConnectionId).SingleOrDefault(); //判断用户是否存在,否则添加集合if (user == null){user = new User("", Context.ConnectionId); users.Add(user); }return base.OnConnected(); }public override Task OnDisconnected(bool stopCalled){var user = users.Where(p => p.ConnectionID == Context.ConnectionId).FirstOrDefault(); //判断用户是否存在,存在则删除if (user != null){//删除用户users.Remove(user); }GetUsers(); //获取所有用户的列表return base.OnDisconnected(stopCalled); }#endregion 方法}public class User{#region 构造函数public User(string name, string connectionId){this.Name = name; this.ConnectionID = connectionId; }#endregion 构造函数#region 属性[Key]public string ConnectionID { get; set; }public string Name { get; set; }#endregion 属性}}
到此这篇关于Asp.net通过SignalR2进行实时聊天的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
推荐阅读
- 使用wordpress中的自定义SQL查询通过wp_get_nav_menu_items提高wp_posts中的查询性能
- ES6中export和import详解(export定义了模块的对外接口后,其他JS文件就可以通过import来加载这个模块)
- python如何将自己的包上传到PyPi并可通过pip安装的方法步骤
- 常见的通过Web API执行associate和disassociate消息示例
- 如何通过手机应用注册Gmail,且跳过手机验证
- 如何通过Filezilla在WordPress上还原以前的自定义媒体存储链接
- 如何通过wordpress API端点返回内容
- 前端|前端学习路线
- 通过添加索引提高应用系统性能
- 如何将变量从一个函数传递到另一个函数并通过短代码显示