所以我用express和nodejs设置了服务器,如下
这是一个迷你项目,它更好地封装了我想要实现的目标:https://file.io/2OFIswnufLFO
我认为主要问题是我认为我的套接字类设置不正确,并且我无法找到任何我能理解的好例子。
有人可以帮助我正确设置我的套接字类,以便我可以在整个后端使用该实例,并且它可以成功向我的所有客户端发出消息(将是 3)
index.js
const express = require('express')
const { createServer } = require("http")
const { Server } = require("socket.io")
const app = express()
const socket = require('./controller/socket.js');
// Initialize socket.io
const httpServer = createServer(app)
socket.connect(httpServer);
httpServer.listen(PORT, () => {
console.log(`App listening on port ${PORT}`)
})
还有我在socket.js中的套接字类:
let connection = null
class Socket {
constructor() {
this._socket = null
}
connect(httpServer) {
const io = require('socket.io')(httpServer, {
cors: {
origin: "*",
// origin: "http://localhost:8080",
methods: ["GET", "POST"]
}
})
io.on('connection', (socket) => {
this._socket = socket
this._socket.on('statusConnetion',(data) => {
console.log(data,'date')
})
this._socket.on('disconnect', function () {
console.log(socket.id,"disconnect")
})
console.log(`New socket connection: ${socket.id}`)
})
}
emitEvent(event, data) {
console.log('sendFromBackendAll')
this._socket.emit(event, data)
}
registerEvent(event, handler) {
this._socket.on(event, handler)
}
static init(server) {
if(!connection) {
connection = new Socket()
connection.connect(server)
}
}
static getConnection() {
if(!connection) {
throw new Error("no active connection")
}
return connection
}
}
module.exports = {
connect: Socket.init,
connection: Socket.getConnection
}
backend.js 文件处理客户端请求
const socket = require(“../controller/socket.js”)
const update_location = (req,res) => {
const connection = socket.connection()
//do update stuff
// successfully complete update
// after successful update query i want to emit so other clients can also update. The below emitEvent works but only from one client
if(connection)connection.emitEvent(“reloadPage”)
// return res.status(200)
}
FRONT_END:
socket.js
import { io } from "socket.io-client";
const URL = "http://localhost:3012";
const socket = io(URL, { autoConnect: true });
在我的 vue 组件中我有监听事件:
async created() {
socket.on("backEmit", () => {
console.log('hi)
});
我运行了两个 vue 客户端。当我启动服务器时,两个前端客户端套接字都会连接并控制台打印
新套接字连接:WpZ_5__1Kq5x_BHZAAAB 新套接字连接:s30YCZ7u1meF_2U4AAAD
当一个客户端提交请求时,会触发发出事件以通知另一个客户端进行更新。 问题是只有一个客户端正在监听,或者它只发送给一个客户端,因为, 假设客户端 1 和客户端 2。
当我从客户端 1 发送请求时,后端发射被触发,客户端 2 听到发射并更新。现在我从客户端 2 发出请求,并且后端发射被触发,但是客户端 1 没有接收发射事件并且没有更新。
因此只有一个客户端听到发出的事件
如果有人能帮忙那就太好了
工作客户端有时可能是#2,而不是#1,具体取决于谁先连接
这应该是您的套接字类。请根据您的需要进行修改,并且必须阅读注释以更好地理解逻辑。
let connection = null;
/** Manage IO and export to use it everywhere in out backend */
let io = null;
/** Manage all user's socket
* We need to emit event for our HTTP request that's why we need to manage all connected user's socket. so we can find user's socket by user id and emit event to that user.
*/
let connectedUsers = {};
class Socket {
constructor() {
}
connect(httpServer) {
io = require('socket.io')(httpServer, {
cors: {
origin: "*",
// origin: "http://localhost:8080",
methods: ["GET", "POST"]
}
})
io.use((socket, next) => {
/** Verify user token and authorize connected client and assign user object with socket */
socket.user = {
id: 1,
name: "John Doe"
}
next();
})
io.on('connection', (socket) => {
connectedUsers[socket.user.id] = socket;
socket.on('statusConnetion',(data) => {
console.log(data,'date')
})
socket.on('disconnect', function () {
console.log(socket.id,"disconnect")
})
console.log(`New socket connection: ${socket.id}`)
})
}
/** Emit event to specific user */
emitEvent(userId, event, data) {
connectedUsers[userId].emit(event, data)
}
/** Emit event to all connected user */
emitEventToAllClient(event, data) {
io.emit(event, data)
}
static init(server) {
if(!connection) {
connection = new Socket()
connection.connect(server)
}
}
static getConnection() {
if(!connection) {
throw new Error("no active connection")
}
return connection
}
}
module.exports = {
connect: Socket.init,
connection: Socket.getConnection
}
您还可以将用户的socketId保存在redis或全局变量中而不是connectedUsers来管理连接的套接字客户端。
如果有帮助请投票并批准我的答案