Vue結(jié)合SignalR實(shí)現(xiàn)前后端實(shí)時(shí)消息同步
最近業(yè)務(wù)中需要實(shí)現(xiàn)服務(wù)器端與客戶端的實(shí)時(shí)通信功能,對(duì)Signalr做了一點(diǎn)總結(jié)和整理。
SignalR 作為 ASP.NET 的一個(gè)庫,能夠簡(jiǎn)單方便地為應(yīng)用提供實(shí)時(shí)的服務(wù)器端與客戶端雙向通信功能。
SignalR 在客戶端方面有兩種API:Connections 和 Hubs。
在特殊情況下,比如發(fā)送消息的格式是特定不變時(shí),使用Connections API。
大多數(shù)情況下使用Hubs,因?yàn)樗?Connections API 更高級(jí)的一種實(shí)現(xiàn),允許客戶端與服務(wù)端相互直接調(diào)用方法。一個(gè)實(shí)際應(yīng)用的具體場(chǎng)景,比如服務(wù)端獲取到新訂單時(shí),調(diào)用客戶端的打印方法,客戶端打印完成后,調(diào)用服務(wù)端的訂單狀態(tài)更新方法。
下面介紹 Hubs 在前端的 API
generated proxy
當(dāng)使用generated proxy的時(shí)候,在語法層面上可以更加簡(jiǎn)單地調(diào)用服務(wù)端方法,就像在服務(wù)端直接調(diào)用。
如下面是服務(wù)端的代碼,表示新增一條聊天信息到列表
public class DemoChatHub : Hub
{
public void NewChatMessage(string name, string message)
{
Clients.All.addMessageToList(name, message);
}
}
客戶端調(diào)用的時(shí)候:
var demoChatHubProxy = $.connection.DemoChatHub;
demoChatHubProxy.client.addMessageToList = function (name, message) {
console.log(name + ' ' + message);
};
$.connection.hub.start().done(function () {
$('#newChatMessage').click(function () {
demoChatHubProxy.server.newChatMessage($('#displayname').val(), $('#message').val());
});
});
不使用 generated proxy 時(shí),客戶端調(diào)用的時(shí)候則是
var connection = $.hubConnection();
var demoChatHubProxy = connection.createHubProxy('demoChatHub');
demoChatHubProxy.on('addMessageToList', function(name, message) {
console.log(name + ' ' + message);
});
connection.start().done(function() {
$('#newChatMessage').click(function () {
demoChatHubProxy.invoke('newChatMessage', $('#displayname').val(), $('#message').val());
});
});
但是在Vue項(xiàng)目里面,如果前后端分離,不會(huì)這樣引用:
<script src="@Url.Content("~/signalr/hubs")" type="text/javascript"></script>
而且在客戶端方法中如果要使用多個(gè)事件處理器時(shí),不能使用generated proxy。
因此后面的例子不采取generated proxy的方式。
1.如何建立連接
var connection = $.hubConnection('localhost:23123');//如果前后端為同一個(gè)端口,可不填參數(shù)。如果前后端分離,這里參數(shù)為服務(wù)器端的URL
var demoChatHubProxy = connection.createHubProxy('demoChatHub');
demoChatHubProxy.on('addMessageToList', function(userName, message) {
console.log(userName + ' ' + message);
});
connection.start()
.done(function(){ console.log('Now connected, connection ID=' + connection.id); })
.fail(function(){ console.log('Could not connect'); });
需要注意的是,開始連接之前(調(diào)用 start 方法之前),最好注冊(cè)至少一個(gè)事件處理方法,如果沒有注冊(cè)的話,Hubs的 OnConnected 方法將不會(huì)被調(diào)用,那么客戶端的方法就不能被服務(wù)端調(diào)用(這容易埋坑,所以要提前注冊(cè)方法)。
2.客戶端如何調(diào)用服務(wù)器端方法
使用 invoke,注意調(diào)用服務(wù)器端的方法名首字母可以不大寫,如果方法名稱要限制必須大寫,需要后端做配置。
demoChatHubProxy.invoke('newChatMessage', {name:'a',message:'b'});
3. 服務(wù)器端調(diào)用客戶端方法
首先客戶端要注冊(cè)方法才能讓服務(wù)器端調(diào)用,使用 on 方法注冊(cè)。
demoChatHubProxy.on('addMessageToList', function(userName, message) {
console.log(userName + ' ' + message);
});
4 在Vue項(xiàng)目中使用SignalR
首先安裝 SignalR 的package,需要注意的是 SignalR 依賴 jQuery。
npm i signalr,jquery
為了方便,在webpack.base.conf.js中注冊(cè)全局的jQuery
plugins: [new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
'root.jQuery': 'jquery'
})
]
然后在main.js中引入 SignalR
import 'signalr'
這時(shí)候就可以在Vue項(xiàng)目中使用SignalR了,后端的相關(guān)配置暫時(shí)略過。
新建一個(gè)signalr.js
import { Message } from 'element-ui';
const HUBNAME = 'DefaultHub';
/*客戶端調(diào)用服務(wù)器端方法*/
//更新訂單打印次數(shù)
const updateOrderPrint = {
name:'updateOrderPrint',
method:function(data){
console.log(data)
}
}
/*服務(wù)器調(diào)用客戶端方法*/
// 打印新訂單
const printNewOrder = {
name:'printNewOrder',
method:function(data){
console.log(data)
}
}
const get = {
name:'Get',
method:function(data){
console.log(data)
}
}
//服務(wù)器端的方法
const serverMethodSets = [updateOrderPrint];
//客戶端的方法
const clientMethodSets = [printNewOrder,get]; //將需要注冊(cè)的方法放進(jìn)集合
// 建立連接
export function startConnection() {
let hub = $.hubConnection(process.env.HUB_API)
let proxy = createHubProxy(hub) //需要先注冊(cè)方法再連接
hub.start().done((connection) =>{
console.log('Now connected, connection ID=' + connection.id)
}).fail(()=>{
Message('連接失敗' + error);
console.log('Could not connect');
})
hub.error(function (error) {
Message('SignalR error: ' + error);
console.log('SignalR error: ' + error)
})
hub.connectionSlow(function () {
console.log('We are currently experiencing difficulties with the connection.')
});
hub.disconnected(function () {
console.log('disconnected')
});
return proxy
}
// 手動(dòng)創(chuàng)建proxy
export function createHubProxy(hub){
let proxy = hub.createHubProxy(HUBNAME)
// 注冊(cè)客戶端方法
clientMethodSets.map((item)=>{
proxy.on(item.name,item.method)
})
return proxy
}
這樣,在組件引入signalr.js后調(diào)用startConnection方法即可建立連接。
了解更多 https://github.com/SignalR/SignalR
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- vue使用stompjs實(shí)現(xiàn)mqtt消息推送通知
- vue實(shí)現(xiàn)消息的無縫滾動(dòng)效果的示例代碼
- 用Vue.extend構(gòu)建消息提示組件的方法實(shí)例
- vue彈窗消息組件的使用方法
- 最簡(jiǎn)單的vue消息提示全局組件的方法
- vue 實(shí)現(xiàn)websocket發(fā)送消息并實(shí)時(shí)接收消息
- Vue $mount實(shí)戰(zhàn)之實(shí)現(xiàn)消息彈窗組件
- 解決vue自定義全局消息框組件問題
- Vue中消息橫向滾動(dòng)時(shí)setInterval清不掉的問題及解決方法
- vue 自定義組件的寫法與用法詳解
- vue2.0 自定義組件的方法(vue組件的封裝)
- vue從零實(shí)現(xiàn)一個(gè)消息通知組件的方法詳解
相關(guān)文章
不同場(chǎng)景下Vue中虛擬列表實(shí)現(xiàn)
虛擬列表用來解決大數(shù)據(jù)量數(shù)據(jù)渲染問題,由于一次性渲染性能低,所以誕生了虛擬列表渲染,下面我們就來學(xué)習(xí)一下不同場(chǎng)景下Vue中虛擬列表是如何實(shí)現(xiàn)的吧2023-10-10
vue項(xiàng)目實(shí)現(xiàn)表單登錄頁保存賬號(hào)和密碼到cookie功能
這篇文章主要介紹了vue項(xiàng)目實(shí)現(xiàn)表單登錄頁保存賬號(hào)和密碼到cookie功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-08-08
Vue iview-admin框架二級(jí)菜單改為三級(jí)菜單的方法
這篇文章主要介紹了Vue iview-admin框架二級(jí)菜單改為三級(jí)菜單的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07
vue2模擬vue-element-admin手寫角色權(quán)限的實(shí)現(xiàn)
本文主要介紹了vue2模擬vue-element-admin手寫角色權(quán)限的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
vue自適應(yīng)布局postcss-px2rem詳解
這篇文章主要介紹了vue自適應(yīng)布局(postcss-px2rem)的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2022-05-05
vue.js 圖片上傳并預(yù)覽及圖片更換功能的實(shí)現(xiàn)代碼
這篇文章主要介紹了vue.js 圖片上傳并預(yù)覽及圖片更換功能,小編主要圍繞我們?nèi)粘J褂霉δ艿睦幼鲋v解,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-08-08

