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 相关文章推荐
javascript firefox兼容ie的dom方法脚本
May 18 Javascript
javascript instanceof 与typeof使用说明
Jan 11 Javascript
jQuery源码分析-01总体架构分析
Nov 14 Javascript
基于JQuery的模拟苹果桌面Dock效果(稳定版)
Oct 15 Javascript
JavaScript Array对象扩展indexOf()方法
May 09 Javascript
jquery 取子节点及当前节点属性值
Jul 25 Javascript
jQuery中clearQueue()方法用法实例
Dec 29 Javascript
基于Jquery实现焦点图淡出淡入效果
Nov 30 Javascript
JavaScript中文件上传API详解
Apr 01 Javascript
Angular数据绑定机制原理
Apr 17 Javascript
vue项目中引入vue-datepicker插件的详解
May 14 Javascript
在Vue中使用Viser说明(基于AntV-G2可视化引擎)
Oct 28 Javascript
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
让你成为更出色的PHP开发者的10个技巧
2011/02/25 PHP
分享下php5类中三种数据类型的区别
2015/01/26 PHP
简单解析PHP程序的运行流程
2016/06/23 PHP
关于php中的json_encode()和json_decode()函数的一些说明
2016/11/20 PHP
比较详细的javascript对象的property和prototype是什么一种关系
2007/08/06 Javascript
javascript SpiderMonkey中的函数序列化如何进行
2012/12/05 Javascript
Jquery加载时从后台读取数据绑定到dropdownList实例
2013/06/09 Javascript
在jquery boxy中添加百度地图坐标拾取注意流程
2014/04/03 Javascript
javascript的tab切换原理与效果实现方法
2015/01/10 Javascript
javascript常见数据验证插件大全
2015/08/03 Javascript
详解iframe与frame的区别
2016/01/13 Javascript
Asp.Net之JS生成分页条的方法
2016/11/23 Javascript
Node之简单的前后端交互(实例讲解)
2017/11/14 Javascript
使用Vue自定义数字键盘组件(体验度极好)
2017/12/19 Javascript
Angular5升级RxJS到5.5.3报错:EmptyError: no elements in sequence的解决方法
2018/04/09 Javascript
图文讲解用vue-cli脚手架创建vue项目步骤
2019/02/12 Javascript
使用Three.js实现太阳系八大行星的自转公转示例代码
2019/04/09 Javascript
JS数据类型(基本数据类型、引用数据类型)及堆和栈的区别分析
2020/03/04 Javascript
JS co 函数库的含义和用法实例总结
2020/04/08 Javascript
selenium 反爬虫之跳过淘宝滑块验证功能的实现代码
2020/08/27 Javascript
详解python时间模块中的datetime模块
2016/01/13 Python
Python中实现最小二乘法思路及实现代码
2018/01/04 Python
python写入已存在的excel数据实例
2018/05/03 Python
如何使用Python发送HTML格式的邮件
2020/02/11 Python
Python全局变量与global关键字常见错误解决方案
2020/10/05 Python
Matplotlib中rcParams使用方法
2021/01/05 Python
html5小程序飞入购物车(抛物线绘制运动轨迹点)
2020/10/19 HTML / CSS
世界上最大的各式箱包网络零售店:eBag
2016/07/21 全球购物
中兴通讯全球官方网站:ZTE
2020/12/26 全球购物
行政管理人员精品工作推荐信
2013/11/04 职场文书
教导处工作制度
2014/01/18 职场文书
《地震中的父与子》教学反思
2014/04/10 职场文书
大专学生求职自荐信
2014/07/06 职场文书
2014年检察院个人工作总结
2014/12/09 职场文书
2015年高校教师个人工作总结
2015/05/25 职场文书
SpringBoot整合MongoDB的实现步骤
2021/06/23 MongoDB