一、eggjs后端:
1.安装插件
npm install egg-socket.io --save
2.注册plugin.js中插件
io: {
enable: true,
package: "egg-socket.io",
},
3.config.default.js中配置插件
config.io = {
init: {},
namespace: {
"/": {
connectionMiddleware: ["connection"], //中间件名称 没有可以为空: ['']
packetMiddleware: ["packet"],// 指定数据包中间件,可选['']
},
},
};
4.创建控制器:controller文件夹下 创建一个叫chat.js的文件
const Controller = require("egg").Controller;
class ChatController extends Controller {
async addId() {
const { ctx, app } = this;
const { id } = ctx.socket;
const message = this.ctx.args[0];
const uid = message.uid;
await app.model.User.update(
{ connect_id: id },
{
where: { id: uid }, // 根据id来更新数据
}
);
console.log(message, id, 2222222222);
}
async onChat(res) {
const { ctx, app } = this;
const { id } = ctx.socket;
const message = this.ctx.args[0];
const uid = message.uid;
const user = await app.model.User.findByPk(uid);
// 在这里处理前端传递过来的值
// await this.ctx.socket.emit("chat", id);
await app.io.to(user.connect_id).emit("chat", message.message);
}
}
module.exports = ChatController;
5.创建socketio路由
module.exports = (app) => {
const { io, router, controller } = app;
io.of("/").route("chat", controller.chat.onChat);
io.of("/").route("addId", controller.chat.addId);
}
//特别注意 route中的chat 与 addId是前端传过来的监听事件
二、vue3前端
1.安装依赖
npm install vue-socket.io --save
2.mainjs中引用依赖
vue3中没有this,所以通过 app.config.globalProperties
注册了一些全局属性和方法,将采用getCurrentInstance
函数来获取当前组件实例,并从中访问全局注册的方法或属性。:
$socket
: 将创建的 VueSocketIO 实例添加到全局属性中,使得在整个 Vue 应用中都能通过$socket
来访问 Socket.io 实例。$addSockets
和$removeSockets
: 分别注册了两个全局方法,用于添加和移除 Socket.io 事件处理函数。
import { createApp } from "vue";
import { createPinia } from "pinia";
import App from "./App.vue";
import router from "./router";
import VueSocketIO from "vue-socket.io";
import { registerSockets, destroySockets } from "../utils/socket"; //具体代码在后面
const socket = new VueSocketIO({
// debug: false,
connection: "http://localhost:7001", //后端地址
autoConnect: false, //禁止自动连接socket,由于不需要一直连socket服务,所以这里设置关闭
options: {
transports: ["websocket"],
},
});
const app = createApp(App);
app.use(createPinia());
app.use(router);
app.config.globalProperties.$socket = socket;
// 监听事件
app.config.globalProperties.$addSockets = registerSockets;
// 移除事件
app.config.globalProperties.$removeSockets = destroySockets;
app.mount("#app");
3.until下创建socket.js直接复制就好
export const registerSockets = (sockets, proxy) => {
sockets &&
Object.keys(sockets).forEach((t) => {
"subscribe" !== t &&
"unsubscribe" !== t &&
proxy.$socket.emitter.addListener(t, sockets[t], proxy);
});
};
export const destroySockets = (sockets, proxy) => {
sockets &&
Object.keys(sockets).forEach((t) => {
proxy.$socket.emitter.removeListener(t, proxy);
});
};
4.在组件中使用
<template>
<div>
<input type="text" v-model="msg" />
<button @click="sendMessage">发送</button> 对方给你发送的消息:{{ newmsg }}
</div>
</template>
<script setup>
import { getCurrentInstance, onBeforeUnmount, onMounted, ref } from "vue";
const { proxy } = getCurrentInstance();
const msg = ref();
const newmsg = ref();
const sockets = {
res(data) {
//后台返回数据
console.log(data);
},
chat(data) {
//可以根据后台添加各种事件 前提是名字和路由一样
newmsg.value = data;
},
};
const key = localStorage.getItem("key");
const sendMessage2 = () => {
proxy.$socket.io.emit("addId", {
//发送内容 数据自己决定传什么
uid: key,
});
};
const sendMessage = () => {
proxy.$socket.io.emit("chat", {
//发送内容 数据自己决定传什么
message: msg.value,
uid: 2,
});
};
onMounted(async () => {
//在onMounted中挂载事件 不挂载的话sockets里的事件好像都监听不到
proxy.$addSockets(sockets, proxy);
sendMessage();
sendMessage2();
});
onBeforeUnmount(() => {
//注销事件
proxy.$removeSockets(sockets, proxy);
});
</script>
此文章是我踩了n多个坑才写出来的,创作不易,如有不理解的可以私信我