前言:最近手上一个项目需要后端实时推送数据到前端,第一个想到的就是微软的SignalR,由于之前都是平时没事写的Demo,没有用到实际项目中,这次恰好用到了,因此记录下来整个实现过程(网上也有很多类似的教程,写的不好,请指正出来)
一、项目准备1、新建一个MVC空项目(过程不在赘述)
2、添加SignalR引用,通过Nuget安装SignalR包。右键引用-》选择管理Nuget程序包-》在出现的窗口中输入SignalR来找到SignalR包进行安装
3、安装SignalR成功后,SignalR库的脚本将被添加进Scripts文件夹下。具体如下图所示:
4、安装Microsoft.Owin以及Microsoft.Owin.Cors,安装方式同前
二、项目构建首先在Models文件夹下面新建一个SignalR集线器(v2)并命名为ChatsHub
然后继续新建接口IChatClient以及IChatService,在ChatsHub.cs中添加以下代码:
[HubName("ChatsHub")] public class ChatsHub : Hub<IChatClient>, IChatService { #region 基础信息 /// <summary> /// 前端自定义参数集合 /// </summary> public INameValueCollection ClientQueryString { get { return Context.QueryString; } } /// <summary> /// Cookie /// </summary> public IDictionary<string, Cookie> ClientCookies { get { return Context.RequestCookies; } } /// <summary> /// 用户信息 /// </summary> public IPrincipal ClientContextUser { get { return Context.User; } } /// <summary> /// SignalR上下文 /// </summary> public HttpContext HttpContext { get { return HttpContext.Current; } } #endregion #region 测试代码 /// <summary> /// 向所有客户端发送消息 /// </summary> /// <param></param> public async Task Send(string message) { try { //当前发送消息的用户ID,前端自定义 //string userId = ClientQueryString["userId"]; //当前连接ID string connId = Context.ConnectionId; //调用所有客户端的SendMessage方法 ChatMessageDTO msg = new ChatMessageDTO { SendId = connId, SendUserName = "", Content = message, CreateDate = DateTime.Now }; await Clients.All.SendMessage(msg); } catch (Exception e) { throw new HubException("发送消息发生异常.", new { userName = ClientContextUser.Identity.Name, message = e.Message }); } } #endregion #region 默认事件 /// <summary> /// 客户端连接的时候调用 /// </summary> /// <returns></returns> public override Task OnConnected() { //string userId = ClientQueryString["userId"]; Trace.WriteLine("客户端连接成功,连接ID是: " + Context.ConnectionId); return base.OnConnected(); } /// <summary> /// 客户端断开连接的时候调用 /// </summary> /// <param></param> /// <returns></returns> public override Task OnDisconnected(bool stopCalled) { Trace.WriteLine($"客户端[{Context.ConnectionId}]断开连接"); return base.OnDisconnected(true); } /// <summary> /// 客户端重新连接的时候调用 /// </summary> /// <returns></returns> public override Task OnReconnected() { Trace.WriteLine($"客户端[{Context.ConnectionId}]正在重新连接"); return base.OnReconnected(); } #endregion }