Vue结合SignalR实现前后端实时消息同步
最近业务中需要实现服务器端与客户端的实时通信功能,对signalr做了一点总结和整理。
signalr 作为 asp.net 的一个库,能够简单方便地为应用提供实时的服务器端与客户端双向通信功能。
signalr 在客户端方面有两种api:connections 和 hubs。
在特殊情况下,比如发送消息的格式是特定不变时,使用connections api。
大多数情况下使用hubs,因为它是 connections api 更高级的一种实现,允许客户端与服务端相互直接调用方法。一个实际应用的具体场景,比如服务端获取到新订单时,调用客户端的打印方法,客户端打印完成后,调用服务端的订单状态更新方法。
下面介绍 hubs 在前端的 api
generated proxy
当使用generated proxy的时候,在语法层面上可以更加简单地调用服务端方法,就像在服务端直接调用。
如下面是服务端的代码,表示新增一条聊天信息到列表
public class demochathub : hub { public void newchatmessage(string name, string message) { clients.all.addmessagetolist(name, message); } }
客户端调用的时候:
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 时,客户端调用的时候则是
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项目里面,如果前后端分离,不会这样引用:
<script src="@url.content("~/signalr/hubs")" type="text/javascript"></script>
而且在客户端方法中如果要使用多个事件处理器时,不能使用generated proxy。
因此后面的例子不采取generated proxy的方式。
1.如何建立连接
var connection = $.hubconnection('localhost:23123');//如果前后端为同一个端口,可不填参数。如果前后端分离,这里参数为服务器端的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'); });
需要注意的是,开始连接之前(调用 start 方法之前),最好注册至少一个事件处理方法,如果没有注册的话,hubs的 onconnected 方法将不会被调用,那么客户端的方法就不能被服务端调用(这容易埋坑,所以要提前注册方法)。
2.客户端如何调用服务器端方法
使用 invoke,注意调用服务器端的方法名首字母可以不大写,如果方法名称要限制必须大写,需要后端做配置。
demochathubproxy.invoke('newchatmessage', {name:'a',message:'b'});
3. 服务器端调用客户端方法
首先客户端要注册方法才能让服务器端调用,使用 on 方法注册。
demochathubproxy.on('addmessagetolist', function(username, message) { console.log(username + ' ' + message); });
4 在vue项目中使用signalr
首先安装 signalr 的package,需要注意的是 signalr 依赖 jquery。
npm i signalr,jquery
为了方便,在webpack.base.conf.js中注册全局的jquery
plugins: [new webpack.provideplugin({ $: 'jquery', jquery: 'jquery', 'window.jquery': 'jquery', 'root.jquery': 'jquery' }) ]
然后在main.js中引入 signalr
import 'signalr'
这时候就可以在vue项目中使用signalr了,后端的相关配置暂时略过。
新建一个signalr.js
import { message } from 'element-ui'; const hubname = 'defaulthub'; /*客户端调用服务器端方法*/ //更新订单打印次数 const updateorderprint = { name:'updateorderprint', method:function(data){ console.log(data) } } /*服务器调用客户端方法*/ // 打印新订单 const printneworder = { name:'printneworder', method:function(data){ console.log(data) } } const get = { name:'get', method:function(data){ console.log(data) } } //服务器端的方法 const servermethodsets = [updateorderprint]; //客户端的方法 const clientmethodsets = [printneworder,get]; //将需要注册的方法放进集合 // 建立连接 export function startconnection() { let hub = $.hubconnection(process.env.hub_api) let proxy = createhubproxy(hub) //需要先注册方法再连接 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 } // 手动创建proxy export function createhubproxy(hub){ let proxy = hub.createhubproxy(hubname) // 注册客户端方法 clientmethodsets.map((item)=>{ proxy.on(item.name,item.method) }) return proxy }
这样,在组件引入signalr.js后调用startconnection方法即可建立连接。
了解更多 https://github.com/signalr/signalr
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: two.js之实现动画效果示例