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的反射问题
Apr 07 Javascript
基于jQuery的合并表格中相同文本的相邻单元格的代码
Apr 06 Javascript
jQuery表单验证插件formValidator(改进版)
Feb 03 Javascript
Js操作Select大全(取值、设置选中等等)
Oct 29 Javascript
JavaScript数据结构和算法之图和图算法
Feb 11 Javascript
浅谈jQuery 中的事件冒泡和阻止默认行为
May 28 Javascript
ES6新特征数字、数组、字符串
Oct 01 Javascript
jQuery扩展+xml实现表单验证功能的方法
Dec 25 Javascript
详解vue2.0组件通信各种情况总结与实例分析
Mar 22 Javascript
js实现点击展开隐藏效果(实例代码)
Sep 28 Javascript
Angular2使用SVG自定义图表(条形图、折线图)组件示例
May 10 Javascript
Swiper.js实现移动端元素左右滑动
Sep 08 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
虹吸式咖啡壶操作
2021/03/03 冲泡冲煮
PHP学习之正则表达式
2011/04/17 PHP
PHP代码优化之成员变量获取速度对比
2014/02/28 PHP
thinkPHP中_initialize方法实例分析
2016/12/05 PHP
PHP通过文件保存和更新信息的方法分析
2019/09/12 PHP
TP5框架请求响应参数实例分析
2019/10/17 PHP
js中字符替换函数String.replace()使用技巧
2011/08/14 Javascript
带左右箭头图片轮播的JS代码
2013/12/18 Javascript
js实现网页随机切换背景图片的方法
2014/11/01 Javascript
dreamweaver 8实现Jquery自动提示
2014/12/04 Javascript
javascript显式类型转换实例分析
2015/04/25 Javascript
JQuery中层次选择器用法实例详解
2015/05/18 Javascript
简介JavaScript中fixed()方法的使用
2015/06/08 Javascript
javascript中JSON对象与JSON字符串相互转换实例
2015/07/11 Javascript
Jquery实现瀑布流布局(备有详细注释)
2015/07/31 Javascript
JavaScript实现带箭头标识的多级下拉菜单效果
2015/08/27 Javascript
在React框架中实现一些AngularJS中ng指令的例子
2016/03/06 Javascript
jQuery+Ajax实现限制查询间隔的方法
2016/06/07 Javascript
PHP抓取HTTPS内容和错误处理的方法
2016/09/30 Javascript
微信小程序使用form表单获取输入框数据的实例代码
2018/05/17 Javascript
浅析前端路由简介以及vue-router实现原理
2018/06/01 Javascript
浅谈vue异步数据影响页面渲染
2019/10/29 Javascript
解决Vue的项目使用Element ui 走马灯无法实现的问题
2020/08/03 Javascript
python和pygame实现简单俄罗斯方块游戏
2021/02/19 Python
django从请求到响应的过程深入讲解
2018/08/01 Python
详解如何为eclipse安装合适版本的python插件pydev
2018/11/04 Python
python使用正则来处理各种匹配问题
2019/12/22 Python
paramiko使用tail实时获取服务器的日志输出详解
2020/12/06 Python
python基于opencv实现人脸识别
2021/01/04 Python
HTML5 Video标签的属性、方法和事件汇总介绍
2015/04/24 HTML / CSS
城市轨道交通工程职业生涯规划书范文
2014/09/16 职场文书
房屋产权证明书
2014/10/15 职场文书
涪陵白鹤梁导游词
2015/02/09 职场文书
酒店财务经理岗位职责
2015/04/08 职场文书
统招统分证明
2015/06/23 职场文书
V Rising 服务器搭建图文教程
2022/06/16 Servers