【问题标题】:Is there a way to get the response for a specific emit using socket.io?有没有办法使用 socket.io 获取特定发射的响应?
【发布时间】:2016-06-06 02:59:17
【问题描述】:

我需要在没有 CORS 标头的服务器上执行 GET 请求,因此我创建了一个非常简单的节点应用程序,它将为我执行 GET:

var io = require('socket.io')();
var request = require('request');

io.on('connection', function(socket) {
  socket.on('get', function(url) {
    request(url, function(error, response, body) {
      socket.emit('response', body);
    });
  });
});

在客户端,我将它与一个简单的get 函数一起使用:

var socket = io();

function get(url) {
  return new Promise(function(resolve) {
    socket.emit('get', url);
    socket.once('response', function(data) {      
      resolve(data);
    });
  }
}

当我一次请求一个 URL 时,这非常有用:

get('http://some/resource/1');

但是当我同时尝试对不同端点的多个请求时,它们都会返回相同的数据:

get('http://some/resource/1');
get('http://some/resource/2');
get('http://some/resource/3');

在这种情况下,所有 3 个请求都返回了 /resource/1 的数据。我理解这是因为所有 3 个请求都立即添加了 socket.once('response') 回调,并且当返回第一个请求的数据时,为它调用所有 3 个回调。

有没有办法让socket.emit()socket.on() 相互配对?我知道我可以为每个发射添加一个唯一 ID 并将其传递回响应,或者在消息本身中使用唯一 ID(类似于 socket.emit('get:a54jk14hf'),但我希望有一个更简单的解决方案)。

【问题讨论】:

    标签: javascript node.js websocket socket.io


    【解决方案1】:

    问题是您正在通过在“get”函数中发出“once”钩子来覆盖 socket.io 的“response”事件。将它保留在那里很好,但您需要为“一次”提供一个独特的事件,这样四个独特的事件就会回来。这可以使用“url”作为键来完成。它看起来像这样:

    服务器:

    var io = require('socket.io')();
    var request = require('request');
    
    io.on('connection', function(socket) {
      socket.on('get', function(url) {
        request(url, function(error, response, body) {
          socket.emit(
            'response-' + url, // USING THIS INSTEAD OF JUST "response"
            body
          );
        });
      });
    });
    

    客户:

    var socket = io();
    
    function get(url) {
      return new Promise(function(resolve) {
        socket.emit('get', url);
        socket.once(
          'response-' + url, // USING THIS INSTEAD OF JUST "response"
          function(data) {      
          resolve(data);
        });
      }
    }
    

    我不确定这是否是您的要求,但上述方法还可以让您始终将正确的数据返回到 Promise 的“then”块。

    get('http://some/resource/1').then(function (data) {            
      // the "data" is now guaranteed to be from resource "1"
      // previous, it could have been from 1, 2, or 3 
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-30
      • 1970-01-01
      • 1970-01-01
      • 2016-01-12
      • 1970-01-01
      • 1970-01-01
      • 2022-06-16
      • 1970-01-01
      相关资源
      最近更新 更多