Vue结合SignalR实现前后端实时消息同步


Posted in Javascript onSeptember 19, 2017

最近业务中需要实现服务器端与客户端的实时通信功能,对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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js更优雅的兼容
Aug 12 Javascript
jQuery实现简单的点赞效果
May 29 Javascript
require.js+vue开发微信上传图片组件
Oct 27 Javascript
浅谈Vue.js中的v-on(事件处理)
Sep 05 Javascript
jQuery实现的简单动态添加、删除表格功能示例
Sep 21 jQuery
Grunt针对静态文件的压缩,版本控制打包的实例讲解
Sep 29 Javascript
使用Vue完成一个简单的todolist的方法
Dec 01 Javascript
javascript实现移动端红包雨页面
Jun 23 Javascript
如何搭建一个完整的Vue3.0+ts的项目步骤
Oct 18 Javascript
VUE和Antv G6实现在线拓扑图编辑操作
Oct 28 Javascript
jQuery实现动态向上滚动
Dec 21 jQuery
详解Vue的sync修饰符
May 15 Vue.js
JavaScript实现的原生态兼容IE6可调可控滚动文字功能详解
Sep 19 #Javascript
vue实现页面加载动画效果
Sep 19 #Javascript
深入理解Node.js中通用基础设计模式
Sep 19 #Javascript
微信小程序媒体组件详解(视频,音乐,图片)
Sep 19 #Javascript
Javascript中将变量转换为字符串的三种方法
Sep 19 #Javascript
详解JS中的this、apply、call、bind(经典面试题)
Sep 19 #Javascript
JavaScript 中的 this 简单规则
Sep 19 #Javascript
You might like
让你同时上传 1000 个文件 (一)
2006/10/09 PHP
php通过执行CutyCapt命令实现网页截图的方法
2016/09/30 PHP
基于CI框架的微信网页授权库示例
2016/11/25 PHP
thinkphp查询,3.X 5.0方法(亲试可行)
2017/06/17 PHP
PHP单例模式应用示例【多次连接数据库只实例化一次】
2018/12/18 PHP
php项目中类的自动加载实例讲解
2019/09/12 PHP
Mootools 1.2教程 Tooltips
2009/09/15 Javascript
关于JavaScript中var声明变量作用域的推断
2010/12/16 Javascript
仿中关村在线首页弹出式广告插件(jQuery版)
2012/05/03 Javascript
详解JS 比较两个Json对象的值是否相等的实例
2013/11/20 Javascript
JavaScript四种调用模式和this示例介绍
2014/01/02 Javascript
js中各种类型的变量在if条件中是true还是false
2014/07/16 Javascript
教你如何使用node.js制作代理服务器
2014/11/26 Javascript
jquery实现点击页面计算点击次数
2015/01/23 Javascript
JavaScript中三个等号和两个等号的区别(== 和 ===)浅析
2016/09/22 Javascript
Webpack执行命令参数详解
2017/06/17 Javascript
AngularJS实现表格的增删改查(仅限前端)
2017/07/04 Javascript
解决vue组件中使用v-for出现告警问题及v for指令介绍
2017/11/11 Javascript
浅谈React前后端同构防止重复渲染
2018/01/05 Javascript
微信小程序文章详情页面实现代码
2018/09/10 Javascript
不刷新网页就能链接新的js文件方法总结
2020/03/01 Javascript
jquery实现淡入淡出轮播图效果
2020/12/13 jQuery
vue中watch的用法汇总
2020/12/28 Vue.js
Python中return self的用法详解
2018/07/27 Python
HTML5注册页面示例代码
2014/03/27 HTML / CSS
video实现有声音自动播放的实现方法
2020/05/20 HTML / CSS
阿迪达斯西班牙官方网站:adidas西班牙
2016/07/21 全球购物
Wedgwood美国官网:英国骨瓷,精美礼品及家居装饰
2018/02/17 全球购物
英国最大的割草机购买网站:Just Lawnmowers
2019/11/02 全球购物
杭州-飞时达软件有限公司.net笔面试
2012/04/28 面试题
毕业自我鉴定范文
2013/11/06 职场文书
网站设计师的岗位职责
2013/11/21 职场文书
校长竞聘演讲稿
2014/05/16 职场文书
企业党员一句话承诺
2014/05/30 职场文书
2015年安全生产目标责任书
2015/01/29 职场文书
入队仪式主持词
2015/07/04 职场文书