2015-11-16 2 views
0

Я объявляю сервер сокета в отдельном модуле. У меня есть доступ к объекту сервера повсюду в приложении, например, я могу отправить. Но я не могу добавить слушателя в маршрут, например:Socket.io добавить слушателей в Express 4 маршрута

router.post('/example', function(req, res, next) { 
    var socketio = req.app.get('sock'); 

    socketio.sockets.on('connection', function (socket) { 
    socket.on('message', function (text) { 
     console.log('ok'); 
    }); 
}); 

Есть ли способ сделать это?

+0

Во-первых, на самом деле нет смысла помещать этот код внутри обработчика маршрута. Обработчик маршрута - это то, что срабатывает, когда какой-либо один клиент попадает в маршрут. Ваши слушатели socket.io должны применяться ко всем клиентам и не зависят от поведения одного клиента. Если вы можете создать резервную копию и описать проблему с более высоким уровнем, которую вы действительно пытаетесь решить здесь, мы можем предложить гораздо лучший подход. – jfriend00

+0

Я пытаюсь создать схему: запрос отправки клиента через http (мой почтовый маршрут), затем сервер отправляет запрос сокета на какое-то устройство, затем сервер получает данные с устройства и отправляет любой результат клиенту через http. –

+0

Извините, я до сих пор не понимаю, что вы пытаетесь сделать. В HTTP-запросе вы обычно просто возвращаете результаты этого запроса в ответ на HTTP-запрос. Почему соединение socket.io связано с HTTP-запросом вообще? Вы все еще не объяснили, почему вам нужно что-то делать с socket.io в этом конкретном запросе HTTP. – jfriend00

ответ

0

Если есть только одно устройство, которое вы хотите общаться и он уже должен быть подключен к серверу и req.app.get('sock'), как вы получите доступ к объекту socketio сервера, то вы можете сделать это следующим образом:

var theDeviceSocket; 
req.app.get('sock').on('connection', function(socket) { 
    theDeviceSocket = socket; 
}); 

router.post('/example', function(req, res, next) { 
    if (theDeviceSocket) { 
     theDeviceSocket.emit("someMsg", "someData"); 
    } 
    // send whatever response you want to send 
    res.end(); 
}); 

Если вы пытались получить ответ от одного устройства и возврата, что в ответ на POST, то вы могли так что-то вроде этого:

// store the one connection to/from the special device 
var theDeviceSocket; 

// keep a request cntr so we can tell which response goes with which request 
var requestCntr = 0; 

req.app.get('sock').on('connection', function(socket) { 
    theDeviceSocket = socket; 
}); 

router.post('/example', function(req, res, next) { 
    var timer, thisRequestId; 

    function gotData(data) { 
     // if this is our specific response 
     if (data.requestId === thisRequestId) { 
      theDeviceSocket.removeListener("someMsgResponse", gotData); 
      res.send(data); 
      clearTimeout(timer); 
     } 
    } 

    if (theDeviceSocket) { 
     theDeviceSocket.on("someMsgResponse", gotData); 
     thisRequestId = requestCntr++; 
     theDeviceSocket.emit("someMsg", {requestId: thisRequestId}); 

     // set up a timeout in case we don't get the proper response 
     timer = setTimeout(function() { 
      theDeviceSocket.removeListener("someMsgResponse", gotData); 
      res.send("error"); 
     }, 5000); 
    } 
}); 

Эта вторая схема осложняется тем фактом, что вы создали ее как схему запроса/ответа, но socket.io не является протоколом запроса/ответа. Таким образом, чтобы узнать, какой ответ относится к какому запросу (когда есть потенциально несколько клиентов, взаимодействующих с сервером в одно и то же время), вы должны реализовать какой-то запрос в данных, которые вы отправляете и получаете через socket.io. Это означает, что вам нужно изменить устройство, чтобы повторить запрос, если вы отправили его с его ответом. Все это не было бы необходимо, если бы вы использовали протокол, предназначенный для запроса/ответа, такого как HTTP, а не socket.io.

+0

Нет вызова 'res.send()', поэтому это ничего не вернет клиенту. Это показывает большую проблему с моделью OP здесь .... запрос POST вызывает эмиссию сообщения через Websocket, а затем сервер должен ждать, пока устройство ответит данными, предназначенными для возврата клиенту. Что делать, если устройство никогда не отвечает? Кроме того, вам понадобится вызов 'res.send()', который будет находиться в обработчике сообщений для сокета, поэтому он может фактически получить доступ к данным, предназначенным для клиента. – djfdev

+0

@djfdev - Я предположил, что OP отправит любой ответ, который им нужен для отправки. Извините, но я не понял из вопроса, что запрос POST должен ожидать ответа от соединения socket.io. Как вы, вероятно, уже можете сказать со всех сторон назад, этот вопрос не очень ясен, поэтому я стараюсь помочь, насколько это возможно, с неясным вопросом. – jfriend00

+0

@djfdev - я добавил больше к моему ответу, но если OP хочет получить запрос/ответ от одного устройства, то socket.io - это просто неправильный тип протокола для этого. Вероятно, они должны просто использовать http. Или, если они будут придерживаться socket.io, им придется указывать запросы и ответы, чтобы они могли быть правильно связаны друг с другом, а другие ответы в полете в то же время можно игнорировать. – jfriend00

Смежные вопросы