目录
安装
nodejs后端:npm install socket.io
vue前端:
-
npm i vue-socket.io -S
-
npm i socket.io-client -S
导入使用
nodejs:
const { Server } = require('socket.io');
const io = new Server(server);
io.on('connection', (socket) => {
console.log('a user connected');
});
前端:
import { io } from 'socket.io-client';
const socket = io("通讯地址");
socket.io特质
事件触发
on接收事件,第一个参数是event,第二个参数是回调函数
emit触发事件,第一个参数是event,第二个参数是事件参数
事件
connection:连接的时候自动触发
disconnect:断开连接的时候自动触发
chat message(随便自定义的名称):点对点通信事件,回调函数里有参数msg(收到的消息),emit的第二个参数则是msg的值,(注意这里的emit如果是对象不需要JSON.stringfy,因为emit里自带这个函数,直接传对象就行)
广播
socket.broadcast.emit('chat message','hello,everyone');
接受还是用chat message事件接收
rooms
io.on('connection', (socket) => {
// join the room named 'some room'
socket.join('some room');
// broadcast to all connected clients in the room
io.to('some room').emit('hello', 'world');
// broadcast to all connected clients except those in the room
io.except('some room').emit('hello', 'world');
// leave the room
socket.leave('some room');
});
断点重连
重连会自己执行,但是再重连过程中丢失的数据不会自动重发,可以采用数据库的方式暂存事件,等connection的时候进行补发
简易聊天室Demo
nodejs后端:
const express = require("express");
const { createServer } = require("node:http");
const { Server } = require("socket.io");
const app = express();
const server = createServer(app);
const io = new Server(server, {
cors: {
origin: "*",
},
});
io.on("connection", (socket) => {
console.log("a user connected");
socket.on("chat message", (msg) => {
console.log(msg);
io.emit("chat message", msg);
});
});
server.listen(3000, () => {
console.log("server running at http://localhost:3000");
});
这里的cors是为了跨域配置的options
vue前端:
<template>
<el-container style="height: 100%;width: 100%;">
<el-header>chat room</el-header>
<ul>
</ul>
<el-footer style="position: fixed;bottom: 0px;width: 300px;height: 50px;">
<el-input v-model="currentMessage" placeholder="Please input" clearable>
<template #append><el-button @click="send">send</el-button></template>
</el-input>
</el-footer>
</el-container>
</template>
<script setup>
import { ref } from 'vue';
import { io } from 'socket.io-client';
// const messages = ref([])
const currentMessage = ref('')
const server = io("ws://127.0.0.1:3000");
server.on('connection', () => {
console.log('connection');
})
server.on('chat message', (msg) => {
const ul = document.querySelector('ul')
const li = document.createElement('li')
li.textContent = msg
ul.appendChild(li)
})
const send = () => {
server.emit('chat message', currentMessage.value)
currentMessage.value = ''
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
a {
color: #42b983;
}
</style>
example:
代码解析:
代码并不困难,后端只要做接收和转发就行,接收chat message然后再把接收到的发出去;前端就是一个按钮触发发送chat message,然后监听chat message进行回显。
这个代码确实很简易,其实不能算聊天室因为区分不了从谁发出来的消息,如果你想要区分,发出去的数据可以设置为一个对象,标记一下源头就行,然后前端可以区分一下源头是不是自己然后用不同的样式进行渲染,因为我只是简单测试一下就没有去区分用户。
但是感觉这个还是有点奇怪,本来我想的是,发送的那个前端在点击send的时候直接回显自己发送的消息,但是后来我发现后端只能给所有的client转发消息,如果发送的那个前端回显的话就会导致他发送的时候回显一次,接受的时候再回显一次,我不知道如何除去发送者,不知道能不能做到,如果有大佬比较了解望指出方法,谢谢。