因爲signalr做爲一個單獨的推送系統,跟業務系統是分離開的,因此此處模擬一個業務系統,新建一個.net core app項目html
咱們的登陸很簡單,當進入系統,若是檢測到用戶未登陸則跳轉到登陸頁面,用戶只須要輸入用戶名點擊登陸即算登陸成功前端
配置ConfigServices方法 查看代碼vue
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, cookieOption => { cookieOption.LoginPath = "/Account/Login"; cookieOption.AccessDeniedPath = "/Account/Login"; });
配置Config方法,配置認證、受權的請求管道 查看代碼git
app.UseRouting(); app.UseAuthentication(); app.UseAuthorization();
首先在Layout頁面引入須要的js文件(vue、signalr、msgpack五、signalr-protocol-msgpack) 查看代碼github
signalr客戶端js的操做就是,建立鏈接、監聽推送,封裝後端js以下 查看代碼ajax
/** * 初始化鏈接 * @param {object} option 參數 * @param {string} option.url 鏈接的url地址 * @param {string} option.loggingLevel 日誌級別,默認爲 Error * @param {number} option.delay 延遲鏈接 默認爲3000毫秒 * @param {function} option.onStarted 啓動時觸發 * @param {function} option.onLine 啓動時觸發 * @param {function} option.offLine 啓動時觸發 * @returns {object} 鏈接的實例 */ function initSignalr(option) { var config = Object.assign(true, { loggingLevel: signalR.LogLevel.Error, delay: 3000, url: '' }, option); var connection = new signalR.HubConnectionBuilder() .configureLogging(config.loggingLevel) .withUrl(config.url, { accessTokenFactory: option.accessTokenFactory }) .withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol()) .withAutomaticReconnect([0, 2000, 5000, 10000, 20000]) .build(); connection.onreconnecting(function (info) { console.info('----------------------------------signalr-- onreconnecting', info); }); connection.onclose(function (err) { console.info('--------------------------------signalr-- onclose', err); }); connection.on('OnNotify', config.onNotify); connection.on('OnLine', config.onLine); connection.on('OffLine', config.offLine); setTimeout(function () { connection.start().then(function (data) { option.onStarted && option.onStarted(data); }).catch(function (error) { console.error(error.toString()); }); }, option.delay); return connection; }
在進入頁面後會彈窗讓用戶輸入加入的組,能夠不輸入也能夠多個segmentfault
function initConnect() { $("#collectionUserInfo").modal({ keyboard: false, show: true, backdrop: 'static' }) $('#collectionUserInfo').on('hidden.bs.modal', function () { var groups = $("#groups").val()||''; connect=initSignalr({ delay: 0, url:`${notifyUrl}notify-hub?userId=${vm.userInfo.userName}&group=${groups}`, loggingLevel: signalR.LogLevel.Error, onNotify: dealNotify, onLine: function (data) { if (data.IsFirst) { getOnlineUsers(); } getOnlineGroups(); vm.logs.push(`新鏈接上線:${JSON.stringify(data)}`); }, offLine: function (data) { if (data.IsLast) { getOnlineUsers(); } getOnlineGroups(); vm.logs.push(`鏈接下線:${JSON.stringify(data)}`); }, onStarted: function () { getOnlineUsers(); getOnlineGroups(); vm.$set(vm.userInfo, 'connectionId', connect.connectionId); vm.$set(vm.userInfo, 'groups', groups); vm.logs.push('鏈接成功'); } }); }) }
onNotify方法,若是仔細的話會看到裏面的onNotify方法,全部的推送最終都會調用到該方法來進行分發。查看代碼
offLine,當有客戶端下線的時候會觸發,data裏面包含有用戶Id、鏈接Id、是否該用戶的最後一個鏈接,可根據須要使用查看代碼
onLine,當用戶鏈接的時候會觸發,data裏面包含有用戶Id、鏈接Id、是否該用戶的第一個鏈接(用於用戶上線後的邏輯處理),可根據須要使用 查看代碼
onStarted,當成功鏈接後觸發,可用於作一些鏈接後的業務邏輯處理,可根據須要使用 查看代碼後端
在用戶鏈接成功後,獲取當前在線用戶、用戶組、當前用戶信息,並設置到vue的data中 查看代碼api
在項目中心中,點擊"模擬推送待辦"按鈕,將會向當前用戶所在組中推送一條代碼消息,能夠登陸不一樣帳號、開多個tab頁體驗
點擊事件代碼位置 查看代碼瀏覽器
assignTaskToUser: function () { var that = this; $.ajax({ type: 'POST', url: '/api/ServerProxy/AssignTaskToUser', data: { groups:that.userInfo.groups } }) },
對應的推送解析代碼
首先當有推送過來的時候,會首先進到onNotify方法,而後根據不一樣類型在分配到不一樣的js方法中
查看代碼
效果圖
登陸互斥是指,當一個帳號在A電腦登陸,而後再在B電腦登陸,最後的登陸會排斥掉開始的登陸,即,將A上的擠下線
首先用谷歌瀏覽器登陸,輸入用戶名:xiexingen,而後鏈接
接着使用360急速瀏覽器登陸,輸入用戶名:xiexingen 這個時候會發現谷歌瀏覽器中的登陸已經退出,如圖
必要條件: 不一樣瀏覽器、同一用戶,好比:同一個瀏覽器,不一樣tab就不算(能共用cookie)
文件下載的場景,用戶在操做頁面上選擇了上千個文件,而後點擊打包下載,這個時候可能須要好久時間才反應回來,那麼這段時間若是讓用戶一直等待顯然不妥,因此,當用戶點擊打包下載的時候,後端啓用一個後臺線程去打包、壓縮,而後當即返回;用戶能夠繼續操做,當服務器端打包好後推送給用戶端,用戶點擊下載便可。
此處分兩種狀況
用戶開了多個tab頁,在其中一個上下載文件,若是後端推送的時候,直接給該用戶推,顯然不妥;正確的作法一個是隻給操做的那個tab頁推,這就須要,調用服務器端業務api的時候,須要把當前tab頁對應的鏈接id發送到服務器端,服務器端處理完業務後,調用推送服務器,告訴推送服務器只推我給你的這個鏈接的客戶端,這樣就能指定鏈接推送。
這種狀況比較少見,告訴推送服務器,給這個用戶,除了某個鏈接外的其餘全部鏈接推送
模擬操做
點擊第一個圖中的"打包下載文件" 按鈕,當前頁面會受到文件下載的推送
在點擊圖二中的"推送當前用戶其餘頁面更新操做"按鈕,會發現出了當前tab頁外,其餘tab也都收到了推送消息,以下圖
至此,signalr相關文章算是到此結束了,下一篇談談我的的一點心得以及裏面存着的一些問題。
標題 | 內容 |
---|---|
索引 | .net core 3.0 Signalr - 實現一個業務推送系統 |
上一篇 | .net core 3.0 Signalr - 07 業務實現-服務端 自定義管理組、用戶、鏈接 |
下一篇 | .net core 3.0 Signalr - 09 待改進&交流 |
源碼地址 | 源碼 |
官方文檔 | 官方文檔 |