Nginx+SignalR+Redis(一)
MVC中SignalR服務端搭建
前言, SignalR即時通訊功能里面有一些前端的類庫不是我自己寫的,我是大自然的搬運工。我只是改吧改吧
最終效果演示
沒個GIF的演示我會拿出來秀?
看上去是不是感覺還可以? 那下面我講解一下開發步驟。
創建MVC項目

為MVC項目在NuGet中引用SignalR
這里用到了NuGet,網上也有很多資源講解怎么使用這個。我這里只大概講解一下。首先打開[工具]-[NuGet 程序包管理器]-[管理解決方案的 NuGet 程序包]

接下來在出現的界面中將程序包源改成:聯機,然后搜索SignalR。接下來自行解決~.~
使用SignalR
需要通過Startup類來配置OWIN程序,所以要在項目中加入一個OWIN Startup類

創建好之后配置注入Redis,設置跨域,並開啟SignalR其中細節不一一介紹

好了下面,我們再為SignalR創建一個集線器Hubs,我的習慣是在項目中創建一個Hubs目錄,然后把需要創建的HubClass放到里面。下面先在項目中創建一個Hubs目錄,再在目錄上單擊右鍵選擇[添加]-[新建項]選擇[SignalR 集線器類]

點擊確定,再把新建的HubClass中的Hello函數干掉。然后在類上增加一個特性:[HubName("systemHub")]。既然是要聊天那么自然離不開用戶,為了方便管理我建立了一個用戶的實體類UserDetail

既然用戶類有了,那么我們可以在Hub里面創建一個用戶池,用來管理在線用戶。
可以將用戶池保存至Redis

現在用戶池有了,下面需要實現三個功能就能進行登錄、上線、下線、私聊操作了。這是下面的邏輯處理代碼:
using CacheRedis; using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Hubs; using SignalChat.Model; using System; using System.Collections.Generic; using System.Linq; namespace SignalRChat.Hubs { [HubName("systemHub")] public class SystemHub : Hub { /// <summary> /// 登錄連線 /// </summary> /// <param name="userID">用戶ID</param> /// <param name="userName">用戶名</param> /// <param name="deptName">部門名</param> public void Connect(string userID, string userName, string deptName) { var id = Context.ConnectionId; List<UserDetail> ConnectedUsers = RedisCache.Hash_GetAll<UserDetail>(Const.UserPool); if (ConnectedUsers.Count(a => a.ConnectionId == id) == 0) { if (ConnectedUsers.Count(x => x.UserID == userID) > 0) { var items = ConnectedUsers.Where(x => x.UserID == userID).ToList(); foreach (var item in items) { Clients.AllExcept(id).onUserDisconnected(item.ConnectionId, item.UserName); } ConnectedUsers.RemoveAll(x => x.UserID == userID); } //添加在線人員 RedisCache.Hash_Set(Const.UserPool, id, new UserDetail { ConnectionId = id, UserID = userID, UserName = userName, DeptName = deptName, LoginTime = DateTime.Now }); // 反饋信息給登錄者 Clients.Caller.onConnected(id, userName, ConnectedUsers); // 通知所有用戶,有新用戶連接 Clients.AllExcept(id).onNewUserConnected(id, userID, userName, deptName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); } else { //已經連接的用戶 } } /// <summary> /// 發送私聊 /// </summary> /// <param name="toUserId">接收方用戶連接ID</param> /// <param name="message">內容</param> public void SendPrivateMessage(string toUserId, string message) { string fromUserId = Context.ConnectionId; List<UserDetail> ConnectedUsers = RedisCache.Hash_GetAll<UserDetail>(Const.UserPool); var toUser = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == toUserId); var fromUser = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == fromUserId); if (toUser != null && fromUser != null) { // send to Clients.Client(toUserId).receivePrivateMessage(fromUserId, fromUser.UserName, message); // send to caller user //Clients.Caller.sendPrivateMessage(toUserId, fromUser.UserName, message); } else { //表示對方不在線 Clients.Caller.absentSubscriber(); } } /// <summary> /// 離線 /// </summary> public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled) { var item = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId); if (item != null) { Clients.All.onUserDisconnected(item.ConnectionId, item.UserName); //調用客戶端用戶離線通知 ConnectedUsers.Remove(item); } return base.OnDisconnected(stopCalled); } } }
我這里寫的邏輯只是一個簡單的示例,這個可以根據自己的想法和需求任意發揮。至此SignalR服務端已經建立完畢。
下面開始建立SignalR瀏覽器客戶端在解決方案上右鍵單擊添加新建項目,如下圖所示

頁面視圖引入一下js

其中<script src="http://localhost:8080/signalr/hubs"></script>是signalr服務端地址
一下為頁面signalr的js介紹
//實例SystemHub,首字母必須小寫才能調用 var systemHub = $.connection.systemHub; //開始鏈接到集線器 $.connection.hub.start().done(function () { //調用服務端函數Connect(首字母小寫)以及傳遞客戶端參數進行上線操作 systemHub.server.connect(userid, username, deptname); }); //新用戶上線 systemHub.client.onNewUserConnected = function (id, userID, userName, deptName, loginTime) { //定義onNewUserConnected客戶端函數供服務端調用 }; //用戶離線 systemHub.client.onUserDisconnected = function (id, userName) { //定義onUserDisconnected客戶端函數供服務端調用 }; //發送消息時,對方已不在線 systemHub.client.absentSubscriber = function () { //定義absentSubscriber客戶端函數供服務端調用 }; //接收消息 systemHub.client.receivePrivateMessage = function (fromUserId, useame, message) { //定義receivePrivateMessage客戶端函數供服務端調用 }; //發送消息 systemHub.server.sendPrivateMessage(ChatCore.nowchat.id, data.content);
SignalRChat
作者太難了給作者點辛苦費吧

