有没有办法使用socket.io?

时间:2016-06-05 12:38:59

标签: javascript node.js websocket socket.io

我需要在没有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的数据。我知道这是因为socket.once('response')回调会立即为所有3个请求添加,并且当返回数据时第一个,为它调用所有3个回调。

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

1 个答案:

答案 0 :(得分:0)

问题是你通过在“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 
})