Мой сценарий - несколько пользователей подключаются к фону через сокеты. Я sh обслуживаю только первое соединение и отклоняю запросы других, основываясь на следующем алгоритме.
Алгоритм следующий: для каждого аутентифицированного соединения сервер должен сначала выбрать определенную запись из базы данных, и если эта запись (определенное поле) равна нулю, обновите указанную запись с идентификатором пользователя, отправленным в запросе.
Теперь, при условии, что два (или более) пользователя подключаются одновременно - они оба «видеть» ноль при запросе к базе данных, предлагая серверу обновлять свои идентификаторы один за другим (исправьте меня, если я ошибаюсь) и в конечном итоге выдает «ack» для них обоих.
Это не мой желаемый результат. Я хочу обновить базу данных только один раз, чтобы любое другое соединение было отклонено, поскольку в базе данных уже существует идентификатор.
Это мой код:
const io = require("socket.io").listen(server);
const db = require("../config/database");
const isEmpty = require("is-empty");
const socketioJwt = require("socketio-jwt");
io.on(
"connection", socketioJwt.authorize({
secret: process.env.secretKey,
handshake: true,
auth_header_required: true,
timeout: 15000 // 15 seconds to send the authentication message
})
).on("authenticated", socket => {
// listen for myEvent
socket.on("myEvent", async req => {
try {
// select a record
const query = `SELECT ... FROM ... WHERE ...`
const result = await db.query(query); //mysql2
// if the result is null, update said record
const query1 = `UPDATE ... SET ... WHERE ...`
await db.query(query1)
// else throw an error
// send "ack" to served (first) connection, others would receive message from onError evt.
socket.emit("myEventAck", /* data */);
} catch (err) {
// log err message to database
io.emit("onError", err.message);
}
});
});
Будет ли этого достаточно? Или мне нужно реализовать какой-то механизм блокировки?