前言因为项目需要在vue中使用websocket,所以找了很多帖子和资料,但是原来的封装逻辑比较复杂,而且它只是为了学习,成本比较高。对于第三方插件,我可以找到vue-socket.io、socket.io和socket.io-client。其中我在使用vue-socket.io和socket.io的时候遇到了一个问题,是全局组件。挂载后找不到io实例,但是找到了io实例和相关方法却无法使用。比如on方法在使用的时候并没有报错,但是console并没有打印后台传输的数据,最后直接找到socket.io-client挂载io实例并使用相关就没有问题了前后传输的方法。希望看到此贴的朋友能给出详细的正确使用vue-socket.io的教程。Socket.ioBrowser和WebServer之间的实时数据传输是一个很重要的需求,但最早只能通过AJAX轮询来实现。在引入WebSocket标准之前,AJAX轮询是一种可行的解决方案。AJAX轮询的原理是设置一个定时器,定时通过AJAX同步服务器数据。这种方法有延迟,对服务器造成很大的负载。直到2011年,IETF才对WebSocket进行了标准化——一种通过TCP套接字发送和接收数据的协议。Socket.io将数据传输部分分离出来形成engine.io。engine.io将WebSocket和AJAX轮询封装成一套API,屏蔽了细节差异和兼容性问题,实现了跨浏览器/跨设备的双向数据通信。websocket协议WebSocket是HTML5中的一种新的通信协议。其特点是服务端可以主动向客户端推送信息,客户端也可以主动向服务端发送信息。是真正的双向平等对话,属于服务器推送技术。种类。在WebSocketAPI中,浏览器和服务器只需要进行一次握手,然后浏览器和服务器之间就形成了一个快速通道,两者可以直接互相传输数据,带来了相互通信的好处。Header很小,只有2Bytes左右。服务器不再是在收到浏览器的请求后被动返回数据,而是在有新数据时主动推送给浏览器。为了建立WebSocket连接,浏览器首先要向服务器发起HTTP请求。这个请求不同于通常的HTTP请求,它包含一些额外的头信息。额外的头信息Upgrade:WebSocket表明这是一个协议升级的HTTP请求。服务端解析头部信息,然后生成响应报文返回给客户端,客户端与服务端的WebSocket连接就建立起来了。双方可以通过这个连接通道自由传输信息,这个连接会一直持续到其中一个客户端或服务器主动关闭连接。为什么使用websocketBrowser已经支持HTTP协议,为什么还要开发一个新的WebSocket协议?我们知道HTTP协议是一种单向网络协议。连接建立后,只有允许Browser/UserAgent向WebServer请求资源后,WebServer才能返回相应的数据,WebServer不能主动向Browser/UserAgent推送数据。当初设计HTTP协议的原因是,假设WebServer可以主动向Browser/UserAgent推送数据,那么Browser/UserAgent太容易受到攻击,一些广告商也会主动强行向其发送广告客户无意中。这不能不说是一场灾难。那么单向HTTP协议给Web应用开发带来了哪些问题呢?现在假设我们要开发一个基于web的应用程序来从当前的WebServer获取实时数据。比如实时股票行情,火车票剩余数量等。这需要Browser/UserAgent和WebServer之间反复进行HTTP通信,Browser/UserAgent不断发送请求获取当前的实时数据。常见的轮询方式是通过Browser/UserAgent定时向WebServer发送HTTP请求。WebServer收到请求后,将最新的数据发回给Browser/UserAgent。Browser/UserAgent获取到数据后,显示出来,然后有规律地重复这个过程。.虽然这样可以满足需求,但是也存在问题。比如WebServer中有一段时间没有更新数据,但是Browser/UserAgent还是会周期性的发送请求去询问,WebServer可以把旧的数据发过去,Browser/UserAgent会发送然后显示这些没有改变的数据。这会浪费网络带宽和CPU利用率。如果增加Browser/UserAgent发送请求的周期可以缓解这个问题,但是如果WebServer的数据更新很快,就不能保证Web应用获取数据的实时性。LongPollingLongPolling是对Polling的改进。Browser/UserAgent向WebServer发送HTTP请求。这时WebServer可以做两件事:如果WebServer有新的数据要传输,它立即将数据发回给Browser/UserAgent。Browser/UserAgent收到数据后,立即再次发送HTTP。请求WebServer。如果WebServer没有新的数据要传输,与Polling的区别在于WebServer不会立即向Browser/UserAgent发送响应,而是保持请求,等待新数据到达后再响应请求。当然,如果WebServer的数据长时间没有更新,HTTP请求会在一段时间后超时。Browser/UserAgent收到超时信息后,会立即向服务器发送新的HTTP请求,然后依次循环这个过程。LongPolling方式虽然可以在一定程度上减少网络带宽和CPU占用率等问题,但是它还是有缺陷的。比如WebServer的数据更新速度更快。在向Browser/UserAgent发送数据包后,WebServer必须等待来自Browser的下一个HTTP请求的到来,然后才能将第二个更新的数据包传递给Browser。在这种情况下,浏览器显示实时数据的最快时间为2xRTT(往返时间)。另外,在网络拥塞的情况下,这应该是用户无法接受的。另外,由于HTTP数据包的头部数据量很大(通常400多字节),而服务器实际需要的数据却很少(有时只有10字节左右),这样的数据包不可避免地要周期性传输浪费网络带宽。综上所述,如果Browser中有一个新的网络,可以支持客户端和服务端的双向通信,而且协议头没有那么庞大,那就太好了。WebSocket就是带着这样的使命登上了Web的舞台。WebSocket的原理WebSocket是一种双向通信协议。它建立在TCP之上。它和HTTP一样通过TCP传输数据,但与HTTP最大的区别是:WebSocket是一种双向通信协议。连接建立后,WebSocket服务器和Browser/UserAgent都可以主动向对象发送或接收数据,就像Socket一样,不同的是WebSocket是一种基于Web的简单模拟Socket协议。WebSocket需要通过握手连接。与TCP类似,客户端和服务器需要进行一次握手连接。只有连接成功后,它们才能相互通信。简单说明WebSocket握手过程。当Web应用程序调用newWebSocket(url)接口时,Browser开始与地址为URL的WebServer建立握手连接的过程。浏览器和WebSocket服务器通过三次TCP握手建立连接。如果连接建立失败,则不会执行后续流程,Web应用会收到错误信息通知。TCP连接建立成功后,Browser/UserAgent通过HTTP协议向服务器发送WebSocket支持的版本号、协议版本号、原始地址、主机地址等一系列字段。WebSocket服务器收到Browser/UserAgent发送的握手请求后,如果报文数据和格式正确,客户端和服务器的协议版本匹配等,则接受握手连接并给出相应的数据回复.同样的回复数据包也是使用HTTP协议传输的。浏览器收到服务器回复的数据包后,如果数据包的内容和格式没有问题,则表示连接成功,触发onopen消息。这时web开发者就可以通过send接口向服务端发送数据了。否则,握手连接失败,Web应用程序将收到一条onerror消息并知道连接失败的原因。WebSocket和TCP的关系,HTTPWebSocket和HTTP协议都是基于TCP的,所以是可靠的协议,Web开发者调用的WebSocket的send函数在Browser的实现中最终是通过TCP的系统接口传递的。WebSocket和HTTP协议都属于应用层协议,那么它们之间有什么关系吗?答案是肯定的,当WebSocket建立握手连接时,数据是通过HTTP协议传输的。但是连接建立之后,真正的数据传输阶段是不需要HTTP参与的。WebSocketServer如果我们要搭建一个WebServer,我们会有很多选择,市面上也有很多成熟的产品供我们使用。例如开源的Apache,安装配置后即可运行。但是如果要搭建一个WebSocket服务器,就没那么容易了,因为WebSocket是一个新的通信协议,还是草案,还没有成为标准,市场上也没有成熟的WebSocket服务器或者类库可以实现WebSocket协议,我们必须自己手动编写代码来解析和组装WebSocket数据包。要完成一个WebSocket服务器,估计大家都想放弃,但是市面上有几个不错的开源库。比如PyWebSocket、WebSocket-Node、LibWebSockets等,这些库都实现了对WebSocket数据包的封装和解析,我们可以调用这些接口,大大减轻了我们的工作量。socket.io-client使用npm官方文档如何使用,通过npm包导入importsocket.io-client,导入前端代码通过src//导入依赖项importiofrom'socket.io-client';exportdefault{data(){return{user:'',message:'',messages:\[\],socket:io('localhost:3001')//挂载依赖}},methods:{sendMessage(e){e.preventDefault();},created(){//向后端发送数据this.socket.emit('sendmessage',{msg:'frontendsendmessage'})//监听来自后端的数据this.socket.on('message',(data)\=>{console.log(data)})}},Node.js服务器代码varapp\=require('express')();varhttp\=require('http').createServer(app);vario\=require('socket.io')(http);/**1。Express初始化应用程序以提供HTTP服务器的函数处理程序(如第2行所示)。2.我们定义一个路由处理程序/当我们访问我们的网站主页时将被调用。3.我们让http服务器监听端口3000*/app.get('/',(req,res)\=>{res.sendFile(\_\_dirname+'/index.html');});//on事件接收信息,这里接收connection事件io.on('connection',(socket)\=>{console.log('auserconnected');//监听前端发送message事件,名称为Custom,但前后端的监听和接受要统一且唯一io.on('sendmessage',(data)\=>{console.log(data)//发送数据通过消息事件发送到前端socket.emit('message',{msg:\`newmessage\`,});})});http.listen(3000,()\=>{console.log('listeningon\*:3000');});我的理解是在使用socket.io时,通过socket.io挂载链接-client依赖,而使用这些方法需要通过socket.io-client创建io实例,所以socket.io官网可以查看相关方法socket.io-client可以使用socket.io中文网socket.io官网。如果想了解更多方法,可以去socket.io官网。从这两段代码可以看出,在socket.io-client中,on表示监听事件,emit表示发送事件,事件名称是自定义的,前后端对this的定义应该保持一致和独特。js原生websocket封装(转载)原生websocket封装vue中原生websocket的使用vue-socket.io使用问题阮一峰websocket教程
