Подтвердить что ты не робот

Node.js socket.io-client событие connect_failed/connect_error

Я играю с node.js и socket.io-client. Я пытаюсь подключиться к каналу, который не существует, чтобы вызвать событие "connect_failed" (как указано в https://github.com/LearnBoost/socket.io-client).

Однако я не могу заставить событие работать:

var clientio = require('socket.io-client');
console.log('Trying stuff ...');

// the channel does not exist
var socket = clientio.connect( 'http://localhost:4000/news' );

// I expect this event to be triggered
socket.on('connect_error', function(){
    console.log('Connection Failed');
});
socket.on('connect', function(){
    console.log('Connected');
});
socket.on('disconnect', function () {
  console.log('Disconnected');
});
socket.send('hi there');

Если я выполню, это произойдет:

$ node tmp_clientio.js 
Trying stuff ...

Любые идеи о том, как вызвать ошибку при подключении к каналу, который не существует?

UPDATE: переименовано connect_failed в connect_error

4b9b3361

Ответ 1

Я столкнулся с той же проблемой. Существует не документированное различие между режимом пространства имен и выключением, с которым я тоже столкнулся, в конце концов мне пришлось использовать хром-отладчик для его работы.

// Bind to the news namespace, also get the underlying socket
var ns_news = clientio.connect( 'http://localhost:4000/news' );
var socket = ns_news.socket

Итак, вы видите выше, что вы должны получить фактический сокет ns_news.socket из своего пространства имен, если вы хотите связать события уровня сокета, такие как сбой соединения, отключение и т.д.

// Global events are bound against socket
socket.on('connect_failed', function(){
    console.log('Connection Failed');
});
socket.on('connect', function(){
    console.log('Connected');
});
socket.on('disconnect', function () {
  console.log('Disconnected');
});


// Your events are bound against your namespace(s)
ns_news.on('myevent', function() {
    // Custom event code here
});

Обратите внимание, что теперь вы используете ns_news для отправки или получения событий

ns_news.send('hi there');

Наконец, обязательно привяжите событие socket.on('error', ...) - это произойдет, если порт недоступен

Полная импликация соединения 8080 с резервностью на порт 80

Я сделал это в своей реализации (попробуйте порт 8080, если это не удается, попробуйте порт 80 через nginx)

socket_port = 8080;

ns_dash = io.connect("http://your.gridspy.co.nz/dash", {
  port: socket_port,
  'connect timeout': 5000,
  'flash policy port': 10843
});

socket = ns_dash.socket;

try_other_port = function() {
  if (socket_port !== 80) {
    if (typeof console !== "undefined" && console !== null) {
      console.log("Trying other port, instead of port " + socket_port + ", attempting port 80");
    }
    socket_port = 80;
    socket.options.port = socket_port;
    socket.options.transports = ['htmlfile', 'xhr-multipart', 'xhr-polling', 'jsonp-polling'];
    return socket.connect();
  } else {
    return typeof console !== "undefined" && console !== null ? console.log("No other ports to try.") : void 0;
  }
};
socket.on('connect_failed', function() {
  if (typeof console !== "undefined" && console !== null) {
    console.log("Connect failed (port " + socket_port + ")");
  }
  return try_other_port();
});
socket.on('error', function() {
  if (typeof console !== "undefined" && console !== null) {
    console.log("Socket.io reported a generic error");
  }
  return try_other_port();
});

Я также добавил правило nginx proxy_pass, которое выглядит как

location ~ ^/(socket.io)/ {
    proxy_pass http://127.0.0.1:8080;
    proxy_http_version 1.1;
    proxy_set_header Host $http_host;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
}

Параметры обновления и подключения здесь (из более поздних версий nginx) необходимы для обновления соединения между nginx и socket.io для поддержки веб-узлов. Это означает, что ваш веб-сервер может поддерживать веб-порты на порту 80.

Кроме того, если ваш сервер поддерживает ssl/https, это будет прокси-сервер wss, который является защищенной версией веб-узлов.

Ответ 3

Из документации:

connect_failed

Вызывается, когда таймаут соединения происходит после последнего соединения попытка. Это срабатывает только в том случае, если установлена ​​опция connectTimeout. Если параметр tryTransportsOnConnectTimeout установлен, это срабатывает только один раз были предприняты попытки транспортировки.

Итак, это событие срабатывает только в том случае, если параметр connectTimeout установлен (реализация для этого здесь: https://github.com/LearnBoost/socket.io-client/blob/master/lib/socket.js#L223-245).

Итак, что вы должны делать в своем коде:

io.connect('http://localhost:4000/news', { 'connect timeout': 5000 }); 
// set connect timeout to 5 seconds

Ответ 4

Это относится к версии 1.4.5 (может также работать и с предыдущими версиями).

Что вы хотите сделать, это прослушать событие "error" в клиенте socket.io. Он инициирует это событие, и сообщение об ошибке будет "Недопустимое пространство имен".

Вот пример того, как обращаться с клиентом socket.io:

  var ioclient = require('socket.io-client');
  var websocket = ioclient('http://myserverurl.com/namespacethatdoesntexist');

  websocket.on('error', function(err){
    if (err == 'Invalid namespace') {
      console.warn("Attempted to connect to invalid namespace");
      //handle the case here...
    } else {
      console.warn("Error on socket.io client", err);
    }
  });