使用WebSocket在vue和egg进行实时通信

4,377 阅读3分钟

什么是WebSocket?

  • WebSocket是HTML5新增的协议,它的目的是在浏览器和服务器之间建立一个不受限的双向通信的通道,比如说,服务器可以在任意时刻发送消息给浏览器。
  • 让浏览器和服务器之间可以建立无限制的全双工通信,任何一方都可以主动发消息给对方。

WebSocket和ajax的区别

1.本质不同

Ajax,即异步JavaScript和XML,是一种创建交互式网页应用的网页开发技术;

WebSocket是HTML5一种新的协议,实现了浏览器与服务器全双工通信。其本质是先通过HTTP/HTTPS协议进行握手后创建一个用于交换数据的TCP连接,服务端与客户端通过此TCP连接进行实时通信。

2.生命周期不同

websocket建立的是长连接,在一个会话中一直保持连接;而ajax是短连接,数据发送和接受完成后就会断开连接。

3.适用范围不同

websocket一般用于前后端实时数据交互,而ajax前后端非实时数据交互。

4.发起人不同

Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以相互推送信息。

vue使用vue-socket.io

1、安装

npm install vue-socket.io 
or
yarn add vue-socket.io 

2、main.js引入

import VueSocketIO from 'vue-socket.io'
Vue.use(new VueSocketIO({
    debug: true,
    connection: 'http://127.0.0.1:5000', //服务端连接
}))

3、在组件中使用

new Vue({
    sockets: {
        connect() {
         //查看socket是否连接成功
            console.log('socket connected')
        },
        res(data) {
         //客户端接收后台传输的socket事件
        // 事件res名字自定义 与服务端的保持一致
          console.log("接收到服务端消息", data);//接收的消息
        }
    },
    methods: {
    //客户端往服务端发消息  
        clickButton: function (data) {
          const val = 'hello,我是客户端,这是发送给你的消息' 
     //res事件与服务端的保持一致
          this.$socket.emit('res', val);
        }
    }
})

egg使用egg-socket.io

1、安装

npm i egg-socket.io 
or
yarn add egg-socket.io

2、在插件中引入

app/config/plugin.js

'use strict';

/** @type Egg.EggPlugin */

//WebSocket
exports.io = {
    enable: true,
    package: 'egg-socket.io'
};

3、配置

app/config/config.default.js

exports.io = {
    namespace: {
        '/': {
            // connectionMiddleware是在client保持连接的时候调用的中间件
            connectionMiddleware: ['auth'],
            // packetMiddleware是在server发送包给client之后调用的中间件
            packetMiddleware: [],
        },
    },
};

4、控制层

  • controller用于处理来自客户端的emit事件。

app/io/middleware/chat.js

module.exports = app => {
    class Controller extends app.Controller {
        async res() {
        //chat事件与客户端的保持一致
            this.ctx.socket.emit('chat', 'hi 我是服务端这是发送给你的消息');
            const params = this.ctx.args[0];
            //通过this.ctx.args[0]可以接受客户端的数据
            // this.ctx.service.message.sendPeerMessage(params);
            console.log('接受客户端消息:', params);
        }
    }
    return Controller
};

5、中间件

app/io/middleware/auth.js

module.exports = app => {
    return async(ctx, next) => {
        ctx.socket.emit('res', 'connected!');
        await next();
        // execute when disconnect.
        console.log('disconnection!');
    };
};

5、路由

app/router.js

'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
    const { router, controller } = app;

    // app.io.route('chat', app.io.controller.chat.res);
    app.io.of('/').route('chat', app.io.controller.chat.res);
};
  • 从上面代码可以知道,在/根路径下,触发socket.emit('chat', 'xxxx') 注意:socket.emit('chat', 'xxxx')chat事件代表路由route('chat'),当执行emit('chat', xxxx)的时候,会触发app/io/controller/chat.js 中的 res 方法,但是在触发之前还要看一下有没有配置中间件,有中间件则先进入中间件

总结

  • 记住一点就是:当使用WebSocket客户端和服务端的自定义的事件名都必须保持一致,才能实现互相推送消息通信

  • 上述代码的只是简单使用WebSocket在vue和egg之间的通信

  • 更复杂的配置的话具体看官方

参考