как положить веб-сокет в базу данных (mongoDB / mon goose)? - PullRequest
1 голос
/ 20 марта 2020

когда игрок входит в систему, я помещаю его веб-сокет в базу данных (понедельник goose смешанный) и сохраняю его. Однако после некоторого тестирования я понимаю, что, если я помещаю веб-сокет в базу данных, веб-сокет становится кучей данных и теряет свой веб-сокет свойства и не могу отправить сообщение пользователю. С другой стороны, если я помещу 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"
});

1 Ответ

0 голосов
/ 20 марта 2020

Вы не можете хранить соединения Websocket: объекты, которые вы называете ws в качестве первого параметра вашего обработчика событий wss.on('connection' ...). Вы не можете хранить их в MongoDB и не можете сериализовать их в JSON: это не чистые данные, а скорее интерфейс для сетевого стека вашей машины.

Итак, вам нужно сохранить их в вашей 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})               
    })
})

Это позволяет вам вернуться к пользователю для определенного соединения, когда вы получаете входящее сообщение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...