工作记录:Vue项目中使用WebSocket通讯
WebSocket介绍
以下内容摘自维基百科:
WebSocket是一种网络传输协议,可在单个TCP连接上进行全双工通信,位于OSI模型的应用层。WebSocket协议在2011年由IETF标准化为RFC 6455,后由RFC 7936补充规范。Web IDL中的WebSocket API由W3C标准化。
WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。
历史
WebSocket最初在HTML5规范中被引用为TCPConnection,作为基于TCP的套接字API的占位符。
WebSocket”这个名字是Ian Hickson和Michael Carter之后在 #whatwg IRC聊天室创造的,随后由Ian Hickson撰写并列入HTML5规范,并在Michael Carter的Cometdaily博客上宣布。
2008年6月,Michael Carter进行了一系列讨论,最终形成了称为WebSocket的协议。
2019年12月谷歌浏览器4率先支持WebSocket并默认开启
2010年2月WebSocket协议有W3C何WHATWG转移到ETF,并在Ian Hickson的指导下进行了两次修订。
2011年12月,WebSocket成为国际通用协议。
背景
WebSocket出现之前,很多网站为了实现推送,所有技术都是使用轮询(每隔一段时间向服务器请求一次最新数据)。这种模式的缺点非常明显:需要不断发送请求,会非常消耗资源。
较新的技术是Comet,这种技术虽然能够实现双向通讯,但是也需要频繁发送请求,颇费资源。
于是,那个男人出现了,WebSocket只需要浏览器与服务器建立一次连接,便可以实现双向实时通讯。
WebSocket的优点
- 实时性。个人认为这是最大的优点,因为这个特性,使得WebSocket在很多应用场景变得非常实用。如游戏、实时在线聊天、实时预警等。
- 较少的控制开销。由于只需要建立一次连接,所以服务器、浏览器开销都较小。并且WebSocket协议数据包头部数据比较小,服务器到浏览器只有2-10字节;而浏览器到服务器之间只需要再加4字节作为掩码。
- 连接状态一直保持。浏览器与服务器之间建立一次有状态连接,除了第一次连接需要携带一些状态数据外,之后的通讯都可以省略。
- 可支持扩展。用户能够根据WebSocket扩展子协议
- 更好的压缩效果。相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。
- 与HTTP协议有这较好的兼容性。默认采用80和443端口,握手阶段采用HTTP协议;因此不容易屏蔽,能够通过这种HTTP代理服务器
- 更好的二进制支持
- 没有同源限制,麻麻再也不用担心我的跨域问题啦~
支持情况

可以看到,现代浏览器都支持WebSocket(包括IE老祖宗,二代目Edge更不用说了,纯现代浏览器),移动端支持情况良好,所以还有什么理由不用呢。
原生的WebSocket
因为实际项目中都会使用相关库(如socket.io),所以本文不讨论原生WebSocket(其实原生也很简单),如果有想学习原生WebSocket的同学,可以看MDN中的WebSocket。
http://www.ruanyifeng.com/blog/2017/05/websocket.html
优秀的WebSocket库
在GitHub上搜索WebSocket,可以看到总共结果有仓库有17K,而JavaScript就有17509个:
- ws:用于nodeJS的后端WebSocket通讯库
- SocketJS:多端可用的WebSocket库,涵盖JavaScript(服务端和客户端)、Erlang、Python/Tornado、Java/vert.x
- socket.io:和SocketJS类似,但是涵盖范围更广:JavaScript(服务端和客户端)、Java、C++、Swift、DartPython、.net。(你问我选哪个?当然是socket.io呀,因为他有vue-socket.io)
- Total.js:用于服务端的NodeJs库
vue项目的话,选用vue-socket.io简直不要太方便,一次建立链接,应用活动期间随意使用,最关键的是,和vuex配合非常友好。
如何在Vue项目中使用
小例子
做了一个小例子,基于vuetify和vue-socket.io的匿名在线聊天系统,可以点击传送门体验WebSocket的快乐。




WebSocket真的能为所欲为

安装
可以通过CDN:https://cdn.jsdelivr.net/npm/vue-socket.io-next@1.1.1/vue-socket.io-next.js
或者通过包管理器:
yarn add vue-socket.io
npm i vue-socket.io
全局使用
在main.ts中添加如下代码:
// 全局使用socket
Vue.use(new VueSocketIO({
debug: true, // 开启socket控制台输出
connection: 'http://39.105.103.136:9521/', // 链接地址
// 配置vuex
vuex: {
store,
actionPrefix: 'socket', // socket触发action的前缀
mutationPrefix: 'socket' // socket触发mutation的前缀
}
}))
其中配置如下:
|
参数 |
类型 |
默认值 |
是否必选 |
描述 |
|
debug |
Boolean |
|
可选 |
启用控制台输出 |
|
connection |
String/Socket.io-client |
|
必选 |
WebSocket服务地址或者Socket.io实例 |
|
vuex.store |
Vuex |
|
可选 |
vuex实例 |
|
vuex.actionPrefix |
String |
|
可选 |
服务端发送消息是对应vuex的action前缀,其格式如下:
|
|
vuex.mutationPrefix |
String |
|
可选 |
服务端发送消息时对应vuex的mutaiton前缀,其格式如下:
|
组件中使用
组件中可以使用实例的$socket.emit()方法,其格式如下:
Vue.$socket.emit(eventName: string,eventData:any)
如:
this.$socket.emit('Login', {
username: this.username
})
订阅与解除订阅
订阅和解除订阅的方法在sockets属性上,其声明文件如下:
interface Vue {
$socket: SocketIOClient.Socket,
sockets: {
subscribe(eventName: string, handler: socketHandler<Vue>): void,
unsubscribe(eventName: string): void,
}
}
所以订阅和接触订阅同理:
this.sockets.subscribe('EVENT_NAME', (data) => {
this.msg = data.message
})
this.sockets.unsubscribe('EVENT_NAME')
与vuex结合
如果在main.ts文件中注入了store,vue-socket.io会在接收到相应消息触发相应的mutation和action,其名称格式为<配置的前缀><消息名>:
export default class Chat extends VuexModule {
onlineUsers: Users = {}
record: Array<Record> = []
@Mutation
// 服务端消息名为Users,socket是soket提交荷载的前缀,data为服务端发送的数据
socketUsers (data: Users) {
this.onlineUsers = data
}
@Mutation
// 服务端消息名为Record,socket是soket提交荷载的前缀,data为服务端发送的数据
socketRecord (data: Array<Record>) {
this.record = data
}
}
工作记录:Vue项目中使用WebSocket通讯的更多相关文章
- Vue项目中使用websocket
<template> <div class="test"> </div> </template> <script> ex ...
- 在vue项目中的axios使用配置记录
默认vue项目中已经安装axios,基于element-ui开发,主要记录配置的相关. axiosConfig.js import Vue from 'vue' import axios from ' ...
- vue项目中遇到的那些事。
前言 有好几天没更新文章了.这段实际忙着做了一个vue的项目,从 19 天前开始,到今天刚好 20 天,独立完成. 做vue项目做这个项目一方面能为工作做一些准备,一方面也精进一下技术. 技术栈:vu ...
- Vue项目中如何使用Element-UI以及如何使用sass
Vue项目中如何使用Element-UI以及如何使用sass 当我们在开发Vue项目的时候通常会选择Element-UI作为我们的UI框架,其官方中文文档地址是http://element.eleme ...
- vue项目中遇到的一些问题
或访问:https://github.com/littleHiuman/experiences-about-vue 欢迎补充! vuex 状态 vue-cli 命令行 vue vue vue-rou ...
- Vue项目中遇到的一些问题总结
一.开发环境使用Ajax请求,报错 网上查的资料,在config中的index.js这样设置 proxyTable:{ '/api':{ target:'', //此处为你的API接口地址 chan ...
- 如何在VUE项目中使用SCSS
首先要了解什么是CSS 预处理器? SCSS是一种CSS预处理语言 定义了一种新的专门的编程语言,编译后形成正常的css文件,为css增加一些编程特性,无需考虑浏览器的兼容性(完全兼容css3),让c ...
- 在vue项目中如何添加eslint
随着vue的越做越好,更多的开发者选择使用vue,本篇记录如何在vue项目中添加eslint. 首先第一种就是在vue项目创建初始时就选择了创建,随着初始化一起代入到了项目当中,那么要是一开始觉得es ...
- vue项目中使用bpmn-自定义platter
前情提要 经过前四篇的学习,我们能够实现bpmn基本绘图.预览.为节点加事件加颜色等效果,这一篇我们来说,如何自定义左侧工具栏(platter),首先看一下自定义前后效果图对比: 我们本次要实现的目标 ...
- vue项目中使用ts(typescript)入门教程
最近项目需要将原vue项目结合ts的使用进行改造,这个后面应该是中大型项目的发展趋势,看到一篇不错的入门教程,结合它并进行了一点拓展记录之.本文从安装到vue组件编写进行了说明,适合入门. 1.引入T ...
随机推荐
- 深入读懂 Kafka集群
前言 概述 Kafka是一个多分区.多副本的分布式流处理平台,以高吞吐.可持久化.可水平扩展.支持流数据处理等多种特性被广泛使用. 应用场景 (1)缓冲削峰:有利于解决生产消息和消费消息的处理速度不一 ...
- java 手写并发框架(一)异步查询转同步的 7 种实现方式
序言 本节将学习一下如何实现异步查询转同步的方式,共计介绍了 7 种常见的实现方式. 思维导图如下: 异步转同步 业务需求 有些接口查询反馈结果是异步返回的,无法立刻获取查询结果. 比如业务开发中我们 ...
- spring boot+sqlite+mybatis实现增删改查例子
主要是更换了下sqlite的数据源而已,其他代码不变. 我都贴一下吧,这个算是比较通用的基础增删改查代码. 1.创建test.db 可以使用Idea自带的Database插件配置,也可以命令行创建,具 ...
- Redis分布式锁的正确使用姿势
前言 分布式锁在日常开发中,用处非常的多.包括但不限于抢红包,秒杀,支付下单,幂等,等等场景. 分布式锁的实现方式有多种,包括redis实现,mysql实现,zookeeper实现等等.而其中redi ...
- win32-SetupDiSetClassInstallParamsW的使用
SetupDiSetClassInstallParams函数一般是用来禁用/启用某个设备 比如我们可以禁用网络适配器 /* for Devpkey */ #define INITGUID /* dep ...
- Redis客户端汇总
编程客户端 已经支持了许多编程语言,详见:https://redis.io/docs/clients/ 图形客户端 1.Another Redis Desktop Manager 支持哨兵, 集群, ...
- 像闪电般击碎天空吧——快速轻量化模型之 SDXL-Lightning
SDXL-Lightning 是一个由 ByteDance(字节跳动) 开发的文本到图像的生成模型,其主要贡献在于其高速的生成能力和轻量化的设计. 模型的特点 快速生成:SDXL-Lightning ...
- 本地配置静态ip和dns及虚拟机
- day03--实际操作演示linux系统挂载过程
# 第一步骤: 拥有一个存储设备-光驱,使光驱加载光盘 # 第二步骤: 在linux系统中找到光驱设备 ls -l /dev/cdrom # 第三步骤: 需要将存储设备进行 挂载 挂载命令语法格式: ...
- 深入解析Python并发编程的多线程和异步编程
本文分享自华为云社区<Python并发编程探秘:多线程与异步编程的深入解析>,作者:柠檬味拥抱. 在Python编程中,多线程是一种常用的并发编程方式,它可以有效地提高程序的执行效率,特别 ...
