记录vue3 ts egg socket.io实现全局推送

1,070 阅读2分钟

记录vue3 ts egg socket.io实现全局推送

egg端

1.安装egg-socket.io
npm i egg-socket.io -save
2.启用egg-socket.io
// 根目录config/plugin.js
module.exports = {
  // socket启用
  io: {
    enable: true,
    package: 'egg-socket.io',
  },
}
3.配置egg-socket.io
// 根目录config/config.default.js
// socket配置
 config.io = {
  // namespace命名空间配置为
  namespace: {
   '/': {
     // 预处理器中间件,对应的文件/app/io/middleware/auth.js, 这里可以配置多个文件, 用逗号隔开
     connectionMiddleware: [ 'auth' ], // 这里我们可以做一些权限校验之类的操作
     packetMiddleware: [], // 对消息做预处理
   },
  },
 };
socket目录结构

s.jpg

4.配置socket路由
//app/router.js
module.exports = app => {
 // socket路由, 指向app/io/controller/chat.js的index方法
 app.io.of('/').route('sendMsg', app.io.controller.chat.index);
};
5.socket中间件
// auth.js
'use strict';
const room = 'default_room'; // 通道名
module.exports = () => {
 return async (ctx, next) => {
  // 加入通道
  ctx.socket.join(room);
  // 放行
  await next();
 };
};
6.socket控制器
'use strict';
const Controller = require('egg').Controller;
const room = 'default_room'; // 通道名,与socket中间件一致
class ChatController extends Controller {
 async index() {
  const { app, socket } = this.ctx;
  const id = socket.id; // 连接ID
  const nsp = app.io.of('/');
  // 根据id给指定连接发送消息
  nsp.sockets[id].emit('res', '发送成功');
  //  给指定通道的成员发送消息
  nsp.to(room).emit('allMsg', {
   id,
   msg: '你好',
  });
 }
}
module.exports = ChatController;
7.可在egg控制器向socket发送消息
'use strict';
const Controller = require('egg').Controller;
class HomeController extends Controller {
  async add_account() {
  const { app, socket } = this.ctx;
  const nsp = app.io.of('/');
  const id = socket.id;
  const room = 'default_room';
  //  给指定通道的成员发送消息
  nsp.to(room).emit('allMsg', {
   id,
   msg: `在egg控制器发送消息`,
  });
 }
}
​
module.exports = HomeController;
​

第六点和第七点的区别是,第六点连接socket进行发送消息,第七点通过发送http请求发送消息

好了,这是serve端的,接下来看一下客户端的,也就是vue端

vue3+ts端

1.安装@types/socket.io-client,以及vue-socket.io

npm install @types/socket.io-client -save
npm install vue-socket.io -save
可能会有版本问题,我这里用的版本是
"@types/socket.io-client": "^1.4.34",
"vue-socket.io": "^3.0.10",

2.全局注册socket.io

// src/io/socket.ts
import socketio from 'socket.io-client'
export default {
 install: (app) => {
  const socketUrl = 'ws://127.0.0.1:7001' // 对应的服务器地址,socket是以ws开头的噢
  // 连接socket
  const socket = socketio.connect(socketUrl, {
   // 使用 websocket
   transports: ['websocket']
  })
  // vue3的全局属性,对标vue2的Vue.prototype
  app.config.globalProperties.$socket = socket
  // 提供数据或提供修改数据的方法,组件用inject使用数据
  app.provide('socket', socket)
 }
}

3.mian.ts注册socket

import { createApp } from 'vue'
import App from '@/App.vue'
import socketIo from './io/socket'createApp(App).use(socketIo).mount('#app')

4.src/app.vue使用socket,单页面可全局收到消息

<template>
 <router-view></router-view>
</template>
<script setup lang="ts">
// 这里用的是vant3.x的提示组件
import { Notify } from 'vant'
import { inject } from "vue"
// 引入全局的socket
const socket: any = inject("socket")
let socketId // 连接id,用于后面接收消息时自身不受到消息,也可在后端处理(暂时没研究)
// 监听socket连接状态
socket.on('connect', () => {
 socketId = socket.id
 console.log(`socket连接已建立成功 socketid: ${socket.id}`)
})
// 接收后端socket返回的消息
socket.on('allMsg', (res) => {
 // 过滤自身
 if (socketId == res.id) return
 Notify({ type: 'primary', message: res.msg });
})
// 监听socket连接断开
socket.on('disconnect', () => {
 console.log('断开连接')
})
</script>
<style>
#app {
 font-family: Avenir, Helvetica, Arial, sans-serif;
 -webkit-font-smoothing: antialiased;
 -moz-osx-font-smoothing: grayscale;
}
</style>

5.src/view/socket.vue发送消息

<template>
  <van-button type="primary" @click="sendMsg">发送消息</van-button>
</template>
<script setup lang="ts">
import { inject } from "vue"
const socket: any = inject("socket")
socket.on('connect', () => {
 console.log(`socket连接已建立成功 socketid: ${socket.id}`)
})
​
const sendMsg = () => {
 socket.emit("sendMsg", '你好');
};
</script>
<style>
</style>

快去试试吧!

本文章参考

www.jianshu.com/p/9f79fd9c8…

juejin.cn/post/699534…

侵权联系删除