Желаемое поведение
В настоящее время я обновляю приложение Node / Express / MongoDB с помощью jQuery.ajax () запросов.
Ответ сервера отправляется обратно в обработчик успеха запроса ajax, и на клиенте отправителя делаются различные изменения интерфейса.
Клиентская сторона
function update_database(parameters) {
$.ajax({
method: "POST",
url: "/api/v1/my_path",
data: parameters,
dataType: 'json',
cache: false,
headers: headers,
success: function(results) {
// perform interface changes
},
statusCode: {
500: function() {
console.log("that didn't work");
}
}
});
}
Конечно, это просто обновляет клиента отправителя.
Я хотел бы обновить все подключенные клиенты.
Что я пробовал
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// send to all clients except sender
socket.broadcast.emit('broadcast', 'hello friends!');
В контексте, раздел Broadcasting
официального руководства показывает:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
io.on('connection', function(socket){
socket.broadcast.emit('hi');
});
Вопрос
Как мне socket.broadcast.emit
из функции обработчика маршрута?
Нужно ли обернуть каждый broadcase.emit
в функцию обратного вызова io.on('connection')
?
Следующее не работает, потому что переменная socket
не была объявлена, но что-то кажется "неправильным" в том, что приходится использовать оболочку io.on('connection')
каждый раз, когда я хочу socket.broadcast.emit
.
Серверная сторона
// app setup
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
// the route handler
app.route("/api/:api_version/my_path")
.post(api_my_post);
// the function
const api_my_post = (req, res) => {
// define the filter and update
var filter = { _id: o_id };
var update = { $set: { key: value } };
// perform the required database update
collection.findOneAndUpdate(filter, update, function(err, result) {
if (err) {
res.send(err);
} else {
// create an object to return
var response_json = { key: value, key_2: value_2 };
// return the object to the ajax success handler
res.json(response_json);
// return the object to all other connected clients
socket.broadcast.emit("ajax_response", response_json);
}
});
}
Edit:
Следующий ответ выглядит многообещающе и относительно просто, но, похоже, отвечает только сценарию io.emit
, а не сценарию socket.broadcast.emit
.
Можно ли каким-то образом получить доступ к socket
в пределах маршрута, чтобы разрешить использование socket.broadcast.emit
?:
https://stackoverflow.com/a/31277123
Базовая конфигурация:
var app = require('express')();
var server = app.listen(process.env.PORT || 3000);
var io = require('socket.io')(server);
// next line is the money
app.set('socketio', io);
Внутренний маршрут или промежуточное ПО:
exports.foo = function(req,res){
// now use socket.io in your routes file
var io = req.app.get('socketio');
io.emit('hi!');
}