当玩家登录时,我将他的websocket放入数据库( Mongoose 混合)并保存。但是,经过一些测试,我明白如果我将websocket放入数据库,websocket会变成一堆数据并丢失其websocket属性并且不能向用户发送消息。另一方面,如果我将 websocket 放入数组中,我完全可以发送消息。有没有办法再次将“一堆数据”转换到 websocket 上?因为我不想有一个庞大的数组来保存用户的 websocket。
app.js(我的服务器)
const express = require('express');
const { createServer } = require("http");
const mongoose = require('mongoose');
const config = require('./config');
const WebSocket = require('ws');
const activeUsers = require("./Models/ActiveUsersModel");
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
const server = createServer(app);
app.locals.wsArray = [];
app.use("/RegisterApi", require("./Routes/RegisterApi/RegisterApi"));
app.use("/MatchMakingApi", require("./Routes/MatchMakingApi/MatchMakerApi"));
const wss = new WebSocket.Server({ server });
server.listen(config.PORT, function () {
console.log(`im listening at ${config.PORT}`);
mongoose.connect(config.MONGODB_URI, {
useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true,
useFindAndModify: false
})
});
//function to split parameters from url
function getVars(tempVars) {
var userObject = {};
tempVars.forEach((a) => {
var splited = a.split("=");
userObject[splited[0]] = splited[1];
});
return userObject;
}
wss.on("connection",async (ws, request) => {
console.log("Total connected clients: ", wss.clients.size);
var tempVars = request.url.split("?")[1].split("&");
var userObject = getVars(tempVars);
console.log(userObject);
const currentUser = await activeUsers.findOne({ _id: userObject.parentID });
console.log('user with id ' + currentUser.currentActiveUser._id + ' login');
currentUser.webSocket = ws;
await currentUser.markModified('webSocket');
await currentUser.save();
app.locals.wsArray.push(ws);
});
const db = mongoose.connection;
db.on('error', (err) => console.log(err))
活跃用户架构
const ActiveUsers = new schema({
currentActiveUser: Users.schema,
webSocket: mongoose.Mixed,
isSearchingGame: {
type: Boolean,
default: false
},
isInMatch: {
type: Boolean,
default: false
}
});
const ActiveUsersModel = mongoose.model("ActiveUsers", ActiveUsers);
module.exports = ActiveUsersModel;
匹配api(服务器中间件)出现错误
router.post('/searchMatch'/*,verifyToken*/, async (req, res) => {
const currentUserData = await activeUsers.findOne({ _id: req.body.tempID });
if (currentUserData.currentActiveUser.money < req.body.money) { res.send('insufficient money'); return; }
req.app.locals.wsArray[0].send('aaaa'); // sends message
await currentUserData.webSocket.send('aaaa'); // gets error " send() isnt a function"
});
最佳答案
您无法存储 Websocket 连接:您调用 ws
的对象作为 wss.on('connection' ...)
事件处理程序的第一个参数。您无法将它们存储在 MongoDB 中,也无法将它们序列化为 JSON:它们不是纯数据,而是机器网络堆栈的接口(interface)。
所以,你需要在你的nodejs程序中维护它们。 Websocket 服务器 (wss
) 有一个 clients
对象。你可以做
wss.clients.forEach(...)
查看所有连接。您可以向连接添加属性,如下所示:
wss.on("connection", async (ws, request) => {
ws.locals = {}
console.log("Total connected clients: ", wss.clients.size)
var tempVars = request.url.split("?")[1].split("&")
var userObject = getVars(tempVars)
ws.locals.parentId = userObject.parentId
const currentUser = await activeUsers.findOne({ _id: userObject.parentID })
wss.on("message", function (event) {
/* retrieve the user */
currentUser = await activeUsers.findOne({ _id: this.locals.parentId})
})
})
这可以让您在收到传入消息时返回到特定连接的用户。
关于node.js - 如何将 websocket 放入数据库(mongoDB/mongoose)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60779057/