Как выполнить socket.broadcast.emit в обработчике маршрутов Express? - PullRequest
0 голосов
/ 10 ноября 2018

Желаемое поведение

В настоящее время я обновляю приложение 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!');
}

1 Ответ

0 голосов
/ 10 ноября 2018

Нет, вы должны реализовать сокетное соединение только один раз, как и передать объект сокета в ваш контроллер

Код BoilerPlate

socket_object = require('./controllers/myapp/socket.js');
io.on('connection', function(socket) {
socket_object(socket);
});

, где socket.js будет иметь функции, подобные

module.exports = function(socket) {

socket.on('getevent', function(data) { 

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