Socket io transport error

I am trying to send a username to the backend upon disconnecting with socket io, when I pass the username as a parameter when unsubscribing from the socket connection it given me the issue transport

I am trying to send a username to the backend upon disconnecting with socket io, when I pass the username as a parameter when unsubscribing from the socket connection it given me the issue transport error.

Here is my code

Client side ‘connection’ is just a variable :

      messages = [];
      connectedUsers = [];
      connection;
      message;
      Username = JSON.parse(localStorage.getItem('user')).username;
      users = [];

ngOnDestroy() {
    this.connection.unsubscribe({username: 'emons'});
}

server side this is where I handle the emit’s the console logs are functional but the ‘console.log(usersConnected[i] +’ was spliced’)’ doesn’t work because the condition is never met:

const app = express();

const port = 3000;
const server = http.Server(app);
const io = socketIo(server);

var usersConnected = [];

    io.on('connection', function(socket){
        console.log('a user connected');
        /*socket.on('new-connection', function(user) {
            io.sockets.emit('newUser', {type: 'new-connection', username: user});
        }); */


        socket.on('disconnect', function(user){
            console.log(user + '   jsjasdjbskjcbawsjbsajdbasjabdsj')
            for (var i = 0; i < usersConnected.length; i++) {
                if (user.username == usersConnected[i]) {
                    usersConnected.splice(i, 1);
                    console.log(usersConnected[i] +' was spliced')
                };
            } 
            console.log(usersConnected);
            console.log('user disconnected');
        });


        socket.on('add-message', function(msg){
            console.log('added message');
            io.sockets.emit('message', {type: 'new-message', username: msg.user, text: msg.message});
        });
        //trying to get all the users.
        socket.on('chat-connection', (data) => {
            socket.join(data.username);
            console.log(data.username);
            usersConnected.push(data.username);
            io.emit('new-user', usersConnected);
        })


    });

chat.service.ts:

   sendMessage(message) {
      this.socket.emit('add-message', message);
    }

    sendUser(user) {
      console.log(user);//print correctly
      this.socket.emit('chat-connection', user);
    }

    removeUser(user) {
      this.socket.emit('remove-user', user);
    }

    getMessages() {
      let observable = new Observable(observer => {
        this.socket = socketIo(this.url);
        this.socket.on('message', (data) => {
          observer.next(data);
        });

        return () => {
          this.socket.disconnect();
        }
      });
      return observable;
    }

  getUsers() {
    let userObservable = new Observable(observer => {
      this.socket = socketIo(this.url);
      this.socket.on('new-user', (data) => {
        observer.next(data);
      });
    });
    return userObservable;
  }

I have the same issue using node.js client with socket.io clent and server version 1.3.7 (latest at this time). I have tried to setup a path as mentioned in the previous comment to no avail. I had no issues getting this to work with the same code using version 0.9.16. This is the last (of many) issues preventing me to upgrade to version 0.9.16, now seriously considering non-socket.io options.

Thanks in advance for your help.

Last client code tried:

var io = require( 'socket.io-client' ); // version 1.3.7
io.connect( 'localhost:8080', { transports: [ 'websocket' ], path: "/socket.io/socket.io.js" } )

Last server code tried:

var socketio = require( 'socket.io' ); // version 1.3.7
var io = socketio.listen( server );
io.use( function( socket, next ) { next() } );
io.sockets.on( 'connection', function( socket ){ ... } )

Here is the full trace:

Mon, 30 Nov 2015 09:42:19 GMT socket.io-client:manager opening https://localhost:8080
Mon, 30 Nov 2015 09:42:19 GMT engine.io-client:socket creating transport "websocket"
Mon, 30 Nov 2015 09:42:19 GMT socket.io-client:manager connect attempt will timeout after 20000
Mon, 30 Nov 2015 09:42:19 GMT engine.io-client:socket setting transport websocket
Mon, 30 Nov 2015 09:42:19 GMT socket.io-client:manager readyState opening
Mon, 30 Nov 2015 09:42:20 GMT engine.io-client:socket socket error {"description":{"code":"ECONNRESET","target":{"domain":null,"_events":{},"_maxListeners":10,"_socket":null,"_ultron":null,"_closeReceived":false,"bytesReceived":0,"readyState":0,"supports":{"binary":true},"extensions":{},"_isServer":false,"url":"wss://localhost:8080/socket.io/socket.io.js/?EIO=3&transport=websocket","protocolVersion":13,"binaryType":"arraybuffer"}}}
Mon, 30 Nov 2015 09:42:20 GMT socket.io-client:manager connect_error
Mon, 30 Nov 2015 09:42:20 GMT engine.io-client:socket socket close with reason: "transport error"
Mon, 30 Nov 2015 09:42:20 GMT socket.io-client:manager will wait 755ms before reconnect attempt
Mon, 30 Nov 2015 09:42:21 GMT socket.io-client:manager attempting reconnect
Mon, 30 Nov 2015 09:42:21 GMT engine.io-client:socket creating transport "websocket"
Mon, 30 Nov 2015 09:42:21 GMT socket.io-client:manager readyState closed
Mon, 30 Nov 2015 09:42:21 GMT engine.io-client:socket setting transport websocket
Mon, 30 Nov 2015 09:42:21 GMT socket.io-client:manager opening https://localhost:8080
Mon, 30 Nov 2015 09:42:21 GMT engine.io-client:socket socket error {"description":{"code":"ECONNRESET","target":{"domain":null,"_events":{},"_maxListeners":10,"_socket":null,"_ultron":null,"_closeReceived":false,"bytesReceived":0,"readyState":0,"supports":{"binary":true},"extensions":{},"_isServer":false,"url":"wss://localhost:8080/socket.io/socket.io.js/?EIO=3&transport=websocket","protocolVersion":13,"binaryType":"arraybuffer"}}}
Mon, 30 Nov 2015 09:42:21 GMT socket.io-client:manager connect attempt will timeout after 20000
... and so on

Устранение проблем с подключением

Common/known issues:

  • сокет не может подключиться
  • сокет отключается
  • сокет застрял в длительном опросе HTTP

Проблема:сокет не может подключиться

Possible explanations:

  • Вы пытаетесь связаться с обычным сервером WebSocket
  • Сервер недоступен
  • Клиент не совместим с версией сервера
  • Сервер не отправляет необходимые CORS-заголовки
  • Вы не включили липкие сеансы (в настройке с несколькими серверами)

Вы пытаетесь связаться с обычным сервером WebSocket

Как объяснялось в разделе «Чем Socket.IO не является» , клиент Socket.IO не является реализацией WebSocket и, следовательно, не сможет установить соединение с сервером WebSocket даже с помощью transports: ["websocket"] :

const socket = io("ws://echo.websocket.org", {
  transports: ["websocket"]
});

Сервер недоступен

Убедитесь,что сервер Socket.IO действительно доступен по указанному URL.Вы можете проверить это с помощью:

curl "<the server URL>/socket.io/?EIO=4&transport=polling"

который должен вернуть что-то вроде этого:

0{"sid":"Lbo5JLzTotvW3g2LAAAA","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":20000}

Если это не так, убедитесь, что сервер Socket.IO работает и что между ними нет ничего, что мешает соединению.

Клиент не совместим с версией сервера

Вот таблица совместимости для JS-клиента :

Версия клиента JS Версия сервера Socket.IO
1.x 2.x 3.x 4.x
1.x YES NO NO NO
2.x NO YES YES1 YES1
3.x NO NO YES YES
4.x NO NO YES YES

[1] Да, с allowEIO3: true

Вот таблица совместимости для Java-клиента :

Версия Java-клиента Версия сервера Socket.IO
2.x 3.x 4.x
1.x YES YES1 YES1
2.x NO YES YES

[1] Да, с allowEIO3: true

Вот таблица совместимости для клиента Swift :

Версия клиента Swift Версия сервера Socket.IO
2.x 3.x 4.x
v15.x YES YES1 YES2
v16.x YES3 YES YES

[1] Да, с allowEIO3: true (сервер) и .connectParams(["EIO": "3"]) (клиент):

SocketManager(socketURL: URL(string:"http://localhost:8087/")!, config: [.connectParams(["EIO": "3"])])

[2] Да, allowEIO3: true (сервер)

[3] Да, с .version(.two) (клиент):

SocketManager(socketURL: URL(string:"http://localhost:8087/")!, config: [.version(.two)])

Если вы видите в консоли следующую ошибку:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at ...

Вероятно,это означает:

  • либо вы на самом деле не подключаетесь к серверу Socket.IO (см. выше )
  • или вы не включили совместное использование ресурсов между источниками (CORS) на стороне сервера.

См. Документацию здесь .

Вы не включили липкие сеансы (в настройке с несколькими серверами)

При масштабировании до нескольких серверов Socket.IO необходимо убедиться, что все запросы данного сеанса Socket.IO достигают одного и того же сервера Socket.IO. Объяснение можно найти здесь .

В противном случае будут получены ответы HTTP 400 с кодом: {"code":1,"message":"Session ID unknown"}

См. Документацию здесь .

Проблема:сокет отключается

Прежде всего,обратите внимание,что обрывы связи-обычное и ожидаемое явление,даже при стабильном интернет-соединении:

  • между пользователем и сервером Socket.IO может произойти временный сбой или перезапуск
  • сам сервер может быть уничтожен в рамках политики автомасштабирования
  • пользователь может потерять соединение или переключиться с WiFi на 4G,в случае мобильного браузера
  • сам браузер может заморозить неактивную вкладку

При этом клиент Socket.IO всегда будет пытаться переподключиться, если не указано иное .

Возможные причины отключения:

  • Вкладка браузера была свёрнута, а пульсация не удалась
  • Клиент не совместим с версией сервера
  • Вы пытаетесь отправить огромный груз

Вкладка браузера была свёрнута, а пульсация не удалась

Когда вкладка браузера не находится в фокусе, некоторые браузеры (например, Chrome ) ограничивают таймеры JavaScript, что может привести к отключению из-за тайм-аута ping в Socket.IO v2 , поскольку механизм пульса основан на функции setTimeout на стороне клиента.

В качестве обходного пути вы можете увеличить значение pingTimeout на стороне сервера:

const io = new Server({
  pingTimeout: 60000
});

Обратите внимание, что обновление до Socket.IO v4 (по крайней мере, socket.io-client@4.1.3 , из-за этого ) должно предотвратить подобные проблемы, поскольку механизм сердцебиения был изменен на противоположный (сервер теперь отправляет пакеты PING).

Клиент не совместим с версией сервера

Поскольку формат пакетов, отправляемых через транспорт WebSocket, аналогичен в v2 и v3/v4, вы можете подключиться к несовместимому клиенту (см. выше ), но соединение в конечном итоге будет закрыто после заданной задержки.

Поэтому, если вы испытываете регулярное отключение через 30 секунд (что было суммой значений pingTimeout и pingInterval в Socket.IO v2), это, безусловно, связано с несовместимостью версий.

Вы пытаетесь отправить огромный груз

Если вы отключились при отправке огромной полезной нагрузки, это может означать, что вы достигли значения maxHttpBufferSize , которое по умолчанию равно 1 МБ. Пожалуйста, настройте его в соответствии с вашими потребностями:

const io = require("socket.io")(httpServer, {
  maxHttpBufferSize: 1e8
});

Огромная полезная нагрузка, для загрузки которой требуется больше времени, чем значение параметра pingTimeout , также может вызвать отключение (поскольку во время загрузки происходит сбой механизма пульса ). Пожалуйста, настройте его в соответствии с вашими потребностями:

const io = require("socket.io")(httpServer, {
  pingTimeout: 60000
});

Проблема:сокет застрял в длинном опросе HTTP

В большинстве случаев вы должны увидеть что-то вроде этого:

Network monitor upon success

  1. рукопожатие Engine.IO (содержит идентификатор сеанса — здесь zBjrh...AAAK — который используется в последующих запросах)
  2. запрос подтверждения Socket.IO (содержит значение параметра auth )
  3. ответ рукопожатия Socket.IO (содержит Socket#id )
  4. соединение WebSocket
  5. первый HTTP-запрос длительного опроса,который закрывается после установления WebSocket-соединения

Если вы не видите ответ HTTP 101 Switching Protocols для 4-го запроса, это означает, что что-то между сервером и вашим браузером препятствует соединению WebSocket.

Обратите внимание,что это не обязательно блокировка,так как соединение все равно устанавливается с помощью HTTP long-polling,но это менее эффективно.

Вы можете получить имя текущего транспорта с помощью:

Client-side

socket.on("connect", () => {
  const transport = socket.io.engine.transport.name; 

  socket.io.engine.on("upgrade", () => {
    const upgradedTransport = socket.io.engine.transport.name; 
  });
});

Server-side

io.on("connection", (socket) => {
  const transport = socket.conn.transport.name; 

  socket.conn.on("upgrade", () => {
    const upgradedTransport = socket.conn.transport.name; 
  });
});

Possible explanations:

  • прокси-сервер перед вашими серверами не принимает WebSocket-соединение

Прокси-сервер перед вашими серверами не принимает WebSocket-соединение

См. Документацию здесь .


Socket.IO

4.5

  • Использование с бандлерами

  • Testing

  • TypeScript

  • Using multiple nodes

Нет документации, это более или менее то, что я могу интерпретировать из кода:

Forced close — Сокет находится в состоянии закрытия

Forced close — https://github.com/socketio/engine.io/blob/master/lib/socket.js

function onPacket(packet){
    if ('ping' == packet.type && 'probe' == packet.data) {
      transport.send([{ type: 'pong', data: 'probe' }]);
      self.emit('upgrading', transport);
      clearInterval(self.checkIntervalTimer);
      self.checkIntervalTimer = setInterval(check, 100);
    } else if ('upgrade' == packet.type && self.readyState != 'closed') {
      debug('got upgrade packet - upgrading');
      cleanup();
      self.upgraded = true;
      self.clearTransport();
      self.setTransport(transport);
      self.emit('upgrade', transport);
      self.setPingTimeout();
      self.flush();
      if (self.readyState == 'closing') {
        transport.close(function () {
          self.onClose('forced close');
        });
      }
    } else {
      cleanup();
      transport.close();
    }
  }


Socket.prototype.close = function () {
  if ('open' != this.readyState) return;

  this.readyState = 'closing';

  if (this.writeBuffer.length) {
    this.once('drain', this.closeTransport.bind(this));
    return;
  }

  this.closeTransport();
};

Транспорт, где он закрыт (здесь нет причин)

Transport close — https://github.com/socketio/engine.io/blob/master/lib/socket.js

 function cleanup() {
    self.upgrading = false;

    clearInterval(self.checkIntervalTimer);
    self.checkIntervalTimer = null;

    clearTimeout(self.upgradeTimeoutTimer);
    self.upgradeTimeoutTimer = null;

    transport.removeListener('packet', onPacket);
    transport.removeListener('close', onTransportClose);
    transport.removeListener('error', onError);
    self.removeListener('close', onClose);
  }


  function onTransportClose(){
    onError("transport closed");
  }

У нас есть клиентский пакет разъединения, поэтому мы меняем состояние сокета на «закрытие»

Client namespace disconnect — https://github.com/socketio/socket.io/blob/master/lib/socket.js

Socket.prototype.onpacket = function(packet){
  debug('got packet %j', packet);
  switch (packet.type) {
    case parser.EVENT:
      this.onevent(packet);
      break;

    case parser.BINARY_EVENT:
      this.onevent(packet);
      break;

    case parser.ACK:
      this.onack(packet);
      break;

    case parser.BINARY_ACK:
      this.onack(packet);
      break;

    case parser.DISCONNECT:
      this.ondisconnect();
      break;

    case parser.ERROR:
      this.emit('error', packet.data);
  }
};


Socket.prototype.ondisconnect = function(){
  debug('got disconnect packet');
  this.onclose('client namespace disconnect');
};

Одна из причин закрытия транспорта

Transport error — https://github.com/socketio/engine.io/blob/master/lib/socket.js

/**
 * Called upon transport error.
 *
 * @param {Error} error object
 * @api private
 */

Socket.prototype.onError = function (err) {
  debug('transport error');
  this.onClose('transport error', err);
};

https://github.com/socketio/engine.io/blob/master/lib/transport.js

/**
 * Called with a transport error.
 *
 * @param {String} message error
 * @param {Object} error description
 * @api private
 */

Transport.prototype.onError = function (msg, desc) {
  if (this.listeners('error').length) {
    var err = new Error(msg);
    err.type = 'TransportError';
    err.description = desc;
    this.emit('error', err);
  } else {
    debug('ignored transport error %s (%s)', msg, desc);
  }
};

Похоже, что они вызывают ошибки в сокетах везде, поэтому единственный способ найти причину — прочитать описание ошибки (не слишком много информации) или посмотреть все их библиотеки, чтобы найти, что вызывает ошибку.

PD: есть много ошибок.

Содержание

  1. Troubleshooting connection issues
  2. In Node.js​
  3. Listening to the connect_error event​
  4. Debug logs​
  5. In the browser​
  6. In the Network Monitor of your browser​
  7. Weird characters in socket.io server response causes parser error #1387
  8. Comments
  9. Current behaviour
  10. Expected behaviour
  11. Setup
  12. Custom parser
  13. Implementing your own parser​
  14. The default parser​
  15. The msgpack parser​
  16. Client API
  17. io.protocol​
  18. io( [url][, options] )​
  19. Initialization examples​
  20. With multiplexing​
  21. With custom path ​
  22. With query parameters​
  23. With query option​
  24. With extraHeaders ​
  25. With websocket transport only​
  26. With a custom parser​
  27. With a self-signed certificate​
  28. Manager​
  29. new Manager(url [, options] )​
  30. manager.reconnection( [value] )​
  31. manager.reconnectionAttempts( [value] )​
  32. manager.reconnectionDelay( [value] )​

Troubleshooting connection issues

First and foremost, please note that disconnections are common and expected, even on a stable Internet connection:

  • anything between the user and the Socket.IO server may encounter a temporary failure or be restarted
  • the server itself may be killed as part of an autoscaling policy
  • the user may lose connection or switch from WiFi to 4G, in case of a mobile browser
  • the browser itself may freeze an inactive tab
  • .

That being said, the Socket.IO client will always try to reconnect, unless specifically told otherwise.

Let’s review how you can troubleshoot a connection failure.

In Node.js​

Listening to the connect_error event​

  • the server might not be reachable

Please make sure the Socket.IO server is actually reachable at the given URL. You can test it with:

which should return something like this:

If that’s not the case, please check that the Socket.IO server is running, and that there is nothing in between that prevents the connection.

  • there might be an issue with the SSL certificate of the server

You can test it with rejectUnauthorized set to false .

If that works, it could mean that the SSL certificate is invalid, or, if you are using a self-signed certificate, that you have to trust it on the client-side:

Debug logs​

As explained here, you can also enable the logs to see what’s going on under the hood.

For reference, here are the logs for a successful connection:

In the browser​

In the Network Monitor of your browser​

In most cases, you should see something like this:

  1. the Engine.IO handshake (contains the session ID — here, zBjrh. AAAK — that is used in subsequent requests)
  2. the Socket.IO handshake request (contains the value of the auth option)
  3. the Socket.IO handshake response (contains the Socket#id)
  4. the WebSocket connection
  5. the first HTTP long-polling request, which is closed once the WebSocket connection is established

The Socket.IO server may return the following HTTP status:

  • 101 Switching Protocols : when the WebSocket connection is established
  • 200 OK : when in HTTP long-polling mode ( GET for reading, POST for writing)
  • 400 Bad Request : when something went wrong

In case of an HTTP 400 response, the response payload will be one of the following:

The transport query parameter is missing or invalid.

To reproduce: curl » /socket.io/» or curl » /socket.io/?transport=udp»

The session ID (included in the sid query parameter) is unknown from the server. That may happen in a multi-server setup.

To reproduce: curl » /socket.io/?transport=polling&sid=1234″

The initial request must be a GET request.

To reproduce: curl -X PUT » /socket.io/?transport=polling»

An error has occurred during the handshake process.

This error cannot be easily reproduced with a single curl command.

The request was denied in the allowRequest handler.

The protocol version is not supported by the server. Support for Socket.IO v2 clients must be explicitly enabled with the allowEIO3 option:

To reproduce: curl » /socket.io/?transport=polling&EIO=3″

Another quite common error is:

Which probably means that you have to enable Cross-Origin Resource Sharing (CORS) on the server-side. Please see the documentation here.

Источник

Weird characters in socket.io server response causes parser error #1387

Current behaviour

I try to connect to a socket.io server with the following code:

Connection fails with the following error:

After debugging a bit, I checked the data my server sent and realized that there are weird characters in the beginning of the response message:

Expected behaviour

I expect the response to include the length of the first message and the «open» message type instead of these weird characters as stated in https://socket.io/docs/internals

Setup

  • OS: Mac OS Catalina 10.15.7
  • socket.io client version: 2.3.1

The text was updated successfully, but these errors were encountered:

Which Socket.IO server are you using? Is it the Javascript implementation (https://github.com/socketio/socket.io)?

@kutluhanmetin could you please open an issue in their issue tracker (here: https://github.com/banacorn/socket.io-haskell) please? (not sure if it is still maintained though)

I guess it is not a server-side bug @darrachequesne because, when I try it with javascript code embedded in html it works. Can it be a specific problem for NodeJS users?

The response of the server looks weird though. Maybe some content encoding issue?

I also encountered this issue. There’s some characters in the beginning of the response of the polling data:

engine.io-client:polling polling got data 96:0

That is why the the socket encounters parse error:

engine.io-client:socket socket receive: type «error», data «parser error»

Closed due to inactivity, please reopen if needed.

Источник

Custom parser

Since Socket.IO v2.0.0, it is now possible to provide your own parser, in order to control the marshalling / unmarshalling of packets.

Implementing your own parser​

Here is a basic example with a parser that uses the JSON.stringify() and JSON.parse() methods:

The default parser​

The source code of the default parser (the socket.io-parser package) can be found here: https://github.com/socketio/socket.io-parser

Example of output:

will be encoded as:

  • emit with binary, acknowledgement and custom namespace

will be encoded as:

  • the binary attachments is then base64-encoded, so this parser is compatible with browsers that do not support Arraybuffers, like IE9
  • packets with binary content are sent as two distinct WebSocket frames (if the WebSocket connection is established)

The msgpack parser​

This parser uses the MessagePack serialization format.

In the browser, there is now an official bundle which includes this parser:

In that case, you don’t need to specify the parser option.

  • packets with binary content are sent as one single WebSocket frame (if the WebSocket connection is established)
  • may results in smaller payloads (especially when using a lot of numbers)
  • incompatible with browsers that do not support Arraybuffers, like IE9
  • harder to debug in the Network tab of the browser

Источник

Client API

Exposed as the io namespace in the standalone build, or the result of calling require(‘socket.io-client’) .

io.protocol​

The protocol revision number (currently: 4).

The protocol defines the format of the packets exchanged between the client and the server. Both the client and the server must use the same revision in order to understand each other.

You can find more information here.

io( [url][, options] )​

  • url (String) (defaults to window.location.host )
  • options (Object)
    • forceNew (Boolean) whether to reuse an existing connection
  • Returns Socket

Creates a new Manager for the given URL, and attempts to reuse an existing Manager for subsequent calls, unless the multiplex option is passed with false . Passing this option is the equivalent of passing ‘force new connection’: true or forceNew: true .

A new Socket instance is returned for the namespace specified by the pathname in the URL, defaulting to / . For example, if the url is http://localhost/users , a transport connection will be established to http://localhost and a Socket.IO connection will be established to /users .

Query parameters can also be provided, either with the query option or directly in the url (example: http://localhost/users?token=abc ).

is the short version of:

See new Manager(url[, options]) for the list of available options .

Initialization examples​

With multiplexing​

By default, a single connection is used when connecting to different namespaces (to minimize resources):

That behaviour can be disabled with the forceNew option:

Note: reusing the same namespace will also create two connections

With custom path ​

The request URLs will look like: localhost/myownpath/?EIO=3&transport=polling&sid=

Here, the socket connects to the admin namespace, with the custom path mypath .

The request URLs will look like: localhost/mypath/?EIO=3&transport=polling&sid= (the namespace is sent as part of the payload).

With query parameters​

With query option​

The query content can also be updated on reconnection:

This only works if polling transport is enabled (which is the default). Custom headers will not be appended when using websocket as the transport. This happens because the WebSocket handshake does not honor custom headers. (For background see the WebSocket protocol RFC)

With websocket transport only​

By default, a long-polling connection is established first, then upgraded to «better» transports (like WebSocket). If you like to live dangerously, this part can be skipped:

With a custom parser​

The default parser promotes compatibility (support for Blob , File , binary check) at the expense of performance. A custom parser can be provided to match the needs of your application. Please see the example here.

With a self-signed certificate​

Manager​

The Manager manages the Engine.IO client instance, which is the low-level engine that establishes the connection to the server (by using transports like WebSocket or HTTP long-polling).

The Manager handles the reconnection logic.

A single Manager can be used by several Sockets. You can find more information about this multiplexing feature here.

Please note that, in most cases, you won’t use the Manager directly but use the Socket instance instead.

new Manager(url [, options] )​

  • url (String)
  • options (Object)
  • Returns Manager
Option Default value Description
path /socket.io name of the path that is captured on the server side
reconnection true whether to reconnect automatically
reconnectionAttempts Infinity number of reconnection attempts before giving up
reconnectionDelay 1000 how long to initially wait before attempting a new reconnection. Affected by +/- randomizationFactor , for example the default initial delay will be between 500 to 1500ms.
reconnectionDelayMax 5000 maximum amount of time to wait between reconnections. Each attempt increases the reconnection delay by 2x along with a randomization factor.
randomizationFactor 0.5 0 timeout 20000 connection timeout before a connect_error and connect_timeout events are emitted
autoConnect true by setting this false, you have to call manager.open whenever you decide it’s appropriate
query <> additional query parameters that are sent when connecting a namespace (then found in socket.handshake.query object on the server-side)
parser the parser to use. Defaults to an instance of the Parser that ships with socket.io. See socket.io-parser.

Available options for the underlying Engine.IO client:

Option Default value Description
upgrade true whether the client should try to upgrade the transport from long-polling to something better.
forceJSONP false forces JSONP for polling transport.
jsonp true determines whether to use JSONP when necessary for polling. If disabled (by settings to false) an error will be emitted (saying «No transports available») if no other transports are available. If another transport is available for opening a connection (e.g. WebSocket) that transport will be used instead.
forceBase64 false forces base 64 encoding for polling transport even when XHR2 responseType is available and WebSocket even if the used standard supports binary.
enablesXDR false enables XDomainRequest for IE8 to avoid loading bar flashing with click sound. default to false because XDomainRequest has a flaw of not sending cookie.
timestampRequests whether to add the timestamp with each transport request. Note: polling requests are always stamped unless this option is explicitly set to false
timestampParam t the timestamp parameter
policyPort 843 port the policy server listens on
transports [‘polling’, ‘websocket’] a list of transports to try (in order). Engine always attempts to connect directly with the first one, provided the feature detection test for it passes.
transportOptions <> hash of options, indexed by transport name, overriding the common options for the given transport
rememberUpgrade false If true and if the previous websocket connection to the server succeeded, the connection attempt will bypass the normal upgrade process and will initially try websocket. A connection attempt following a transport error will use the normal upgrade process. It is recommended you turn this on only when using SSL/TLS connections, or if you know that your network does not block websockets.
onlyBinaryUpgrades false whether transport upgrades should be restricted to transports supporting binary data
requestTimeout timeout for xhr-polling requests in milliseconds ( 0 ) (only for polling transport)
protocols a list of subprotocols (see MDN reference) (only for websocket transport)

Node.js-only options for the underlying Engine.IO client:

Option Default value Description
agent false the http.Agent to use
pfx Certificate, Private key and CA certificates to use for SSL.
key Private key to use for SSL.
passphrase A string of passphrase for the private key or pfx.
cert Public x509 certificate to use.
ca An authority certificate or array of authority certificates to check the remote host against.
ciphers A string describing the ciphers to use or exclude. Consult the cipher format list for details on the format.
rejectUnauthorized false If true, the server certificate is verified against the list of supplied CAs. An ‘error’ event is emitted if verification fails. Verification happens at the connection level, before the HTTP request is sent.
perMessageDeflate true parameters of the WebSocket permessage-deflate extension (see ws module api docs). Set to false to disable.
extraHeaders <> Headers that will be passed for each request to the server (via xhr-polling and via websockets). These values then can be used during handshake or for special proxies.
forceNode false Uses NodeJS implementation for websockets — even if there is a native Browser-Websocket available, which is preferred by default over the NodeJS implementation. (This is useful when using hybrid platforms like nw.js or electron)
localAddress the local IP address to connect to

manager.reconnection( [value] )​

  • value (Boolean)
  • Returns Manager|Boolean

Sets the reconnection option, or returns it if no parameters are passed.

manager.reconnectionAttempts( [value] )​

  • value (Number)
  • Returns Manager|Number

Sets the reconnectionAttempts option, or returns it if no parameters are passed.

manager.reconnectionDelay( [value] )​

  • value (Number)
  • Returns Manager|Number

Sets the reconnectionDelay option, or returns it if no parameters are passed.

Источник

Table of content

  • Creation of a Socket instance
  • Default values
  • Description
    • IO factory options
      • forceNew
      • multiplex
    • Low-level engine options
      • transports
      • upgrade
      • rememberUpgrade
      • path
      • query
      • extraHeaders
      • callFactory
      • webSocketFactory
    • Manager options
      • reconnection
      • reconnectionAttempts
      • reconnectionDelay
      • reconnectionDelayMax
      • randomizationFactor
      • timeout
    • Socket options
      • auth
  • SSL connections
    • With a keystore
    • Trust all certificates
  • Multiplexing

Creation of a Socket instance

URI uri = URI.create("https://example.com");
IO.Options options = IO.Options.builder()
        // ...
        .build();

Socket socket = IO.socket(uri, options);

Unlike the JS client (which can infer it from the window.location object), the URI is mandatory here.

The scheme part of the URI is also mandatory. Both ws:// and http:// can be used interchangeably.

Socket socket = IO.socket("https://example.com"); // OK
Socket socket = IO.socket("wss://example.com"); // OK, similar to the example above
Socket socket = IO.socket("192.168.0.1:1234"); // NOT OK, missing the scheme part

The path represents the Namespace, and not the actual path (see below) of the HTTP requests:

Socket socket = IO.socket(URI.create("https://example.com")); // the main namespace
Socket productSocket = IO.socket(URI.create("https://example.com/product")); // the "product" namespace
Socket orderSocket = IO.socket(URI.create("https://example.com/order")); // the "order" namespace

Default values

IO.Options options = IO.Options.builder()
    // IO factory options
    .setForceNew(false)
    .setMultiplex(true)

    // low-level engine options
    .setTransports(new String[] { Polling.NAME, WebSocket.NAME })
    .setUpgrade(true)
    .setRememberUpgrade(false)
    .setPath("/socket.io/")
    .setQuery(null)
    .setExtraHeaders(null)

    // Manager options
    .setReconnection(true)
    .setReconnectionAttempts(Integer.MAX_VALUE)
    .setReconnectionDelay(1_000)
    .setReconnectionDelayMax(5_000)
    .setRandomizationFactor(0.5)
    .setTimeout(20_000)

    // Socket options
    .setAuth(null)
    .build();

Description

IO factory options

These settings will be shared by all Socket instances attached to the same Manager.

forceNew

Default value: false

Whether to create a new Manager instance.

A Manager instance is in charge of the low-level connection to the server (established with HTTP long-polling or WebSocket). It handles the reconnection logic.

A Socket instance is the interface which is used to sends events to — and receive events from — the server. It belongs to a given namespace.

A single Manager can be attached to several Socket instances.

The following example will reuse the same Manager instance for the 3 Socket instances (one single WebSocket connection):

IO.Options options = IO.Options.builder()
        .setForceNew(false)
        .build();

Socket socket = IO.socket(URI.create("https://example.com"), options); // the main namespace
Socket productSocket = IO.socket(URI.create("https://example.com/product"), options); // the "product" namespace
Socket orderSocket = IO.socket(URI.create("https://example.com/order"), options); // the "order" namespace

The following example will create 3 different Manager instances (and thus 3 distinct WebSocket connections):

IO.Options options = IO.Options.builder()
        .setForceNew(true)
        .build();

Socket socket = IO.socket(URI.create("https://example.com"), options); // the main namespace
Socket productSocket = IO.socket(URI.create("https://example.com/product"), options); // the "product" namespace
Socket orderSocket = IO.socket(URI.create("https://example.com/order"), options); // the "order" namespace

multiplex

Default value: true

The opposite of forceNew: whether to reuse an existing Manager instance.

Low-level engine options

transports

Default value: new String[] { Polling.NAME, WebSocket.NAME }

The low-level connection to the Socket.IO server can either be established with:

  • HTTP long-polling: successive HTTP requests (POST for writing, GET for reading)
  • WebSocket

The following example disables the HTTP long-polling transport:

IO.Options options = IO.Options.builder()
        .setTransports(new String[] { WebSocket.NAME })
        .build();

Socket socket = IO.socket(URI.create("https://example.com"), options);

Note: in that case, sticky sessions are not required on the server side (more information here).

upgrade

Default value: true

Whether the client should try to upgrade the transport from HTTP long-polling to something better.

rememberUpgrade

Default value: false

If true and if the previous WebSocket connection to the server succeeded, the connection attempt will bypass the normal upgrade process and will initially try WebSocket. A connection attempt following a transport error will use the normal upgrade process. It is recommended you turn this on only when using SSL/TLS connections, or if you know that your network does not block websockets.

path

Default value: /socket.io/

It is the name of the path that is captured on the server side.

The server and the client values must match:

Client

IO.Options options = IO.Options.builder()
        .setPath("/my-custom-path/")
        .build();

Socket socket = IO.socket(URI.create("https://example.com"), options);

JavaScript Server

import { Server } from "socket.io";

const io = new Server(8080, {
  path: "/my-custom-path/"
});

io.on("connection", (socket) => {
  // ...
});

Please note that this is different from the path in the URI, which represents the Namespace.

Example:

IO.Options options = IO.Options.builder()
        .setPath("/my-custom-path/")
        .build();

Socket socket = IO.socket(URI.create("https://example.com/order"), options);
  • the Socket instance is attached to the “order” Namespace
  • the HTTP requests will look like: GET https://example.com/my-custom-path/?EIO=4&transport=polling&t=ML4jUwU

query

Default value: —

Additional query parameters (then found in socket.handshake.query object on the server-side).

Example:

Client

IO.Options options = IO.Options.builder()
        .setQuery("x=42")
        .build();

Socket socket = IO.socket(URI.create("https://example.com"), options);

JavaScript Server

io.on("connection", (socket) => {
  console.log(socket.handshake.query); // prints { x: '42', EIO: '4', transport: 'polling' }
});

Note: The socket.handshake.query object contains the query parameters that were sent during the Socket.IO handshake, it won’t be updated for the duration of the current session, which means changing the query on the client-side will only be effective when the current session is closed and a new one is created:

socket.io().on(Manager.EVENT_RECONNECT_ATTEMPT, new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        options.query = "y=43";
    }
});

extraHeaders

Default value: —

Additional headers (then found in socket.handshake.headers object on the server-side).

Example:

Client

IO.Options options = IO.Options.builder()
        .setExtraHeaders(singletonMap("authorization", singletonList("bearer 1234")))
        .build();

Socket socket = IO.socket(URI.create("https://example.com"), options);

JavaScript Server

io.on("connection", (socket) => {
  console.log(socket.handshake.headers); // prints { accept: '*/*', authorization: 'bearer 1234', connection: 'Keep-Alive', 'accept-encoding': 'gzip', 'user-agent': 'okhttp/3.12.12' }
});

Note: Similar to the query option above, the socket.handshake.headers object contains the headers that were sent during the Socket.IO handshake, it won’t be updated for the duration of the current session, which means changing the extraHeaders on the client-side will only be effective when the current session is closed and a new one is created:

socket.io().on(Manager.EVENT_RECONNECT_ATTEMPT, new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        options.extraHeaders.put("authorization", singletonList("bearer 5678"));
    }
});

callFactory

The OkHttpClient instance to use for HTTP long-polling requests.

OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .readTimeout(1, TimeUnit.MINUTES) // important for HTTP long-polling
        .build();

IO.Options options = new IO.Options();
options.callFactory = okHttpClient;

Socket socket = IO.socket(URI.create("https://example.com"), options);

webSocketFactory

The OkHttpClient instance to use for WebSocket connections.

OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .minWebSocketMessageToCompress(2048)
        .build();

IO.Options options = new IO.Options();
options.webSocketFactory = okHttpClient;

Socket socket = IO.socket(URI.create("https://example.com"), options);

Manager options

These settings will be shared by all Socket instances attached to the same Manager.

reconnection

Default value: true

Whether reconnection is enabled or not. If set to false, you need to manually reconnect.

reconnectionAttempts

Default value: Integer.MAX_VALUE

The number of reconnection attempts before giving up.

reconnectionDelay

Default value: 1_000

The initial delay before reconnection in milliseconds (affected by the randomizationFactor value).

reconnectionDelayMax

Default value: 5_000

The maximum delay between two reconnection attempts. Each attempt increases the reconnection delay by 2x.

randomizationFactor

Default value: 0.5

The randomization factor used when reconnecting (so that the clients do not reconnect at the exact same time after a server crash, for example).

Example with the default values:

  • 1st reconnection attempt happens between 500 and 1500 ms (1000 * 2^0 * (<something between -0.5 and 1.5>))
  • 2nd reconnection attempt happens between 1000 and 3000 ms (1000 * 2^1 * (<something between -0.5 and 1.5>))
  • 3rd reconnection attempt happens between 2000 and 5000 ms (1000 * 2^2 * (<something between -0.5 and 1.5>))
  • next reconnection attempts happen after 5000 ms

timeout

Default value: 20_000

The timeout in milliseconds for each connection attempt.

Socket options

These settings are specific to the given Socket instance.

auth

Default value: —

Credentials that are sent when accessing a namespace (see also here).

Example:

Client

IO.Options options = IO.Options.builder()
        .setAuth(singletonMap("token", "abcd"))
        .build();

Socket socket = IO.socket(URI.create("https://example.com"), options);

JavaScript Server

io.on("connection", (socket) => {
  console.log(socket.handshake.auth); // prints { token: 'abcd' }
});

You can update the auth map when the access to the Namespace is denied:

socket.on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        options.auth.put("token", "efgh");
        socket.connect();
    }
});

Or manually force the Socket instance to reconnect:

options.auth.put("token", "efgh");
socket.disconnect().connect();

SSL connections

With a keystore

HostnameVerifier hostnameVerifier = new HostnameVerifier() {
    public boolean verify(String hostname, SSLSession sslSession) {
        return hostname.equals("example.com");
    }
};

KeyStore ks = KeyStore.getInstance("JKS");
File file = new File("path/to/the/keystore.jks");
ks.load(new FileInputStream(file), "password".toCharArray());

KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, "password".toCharArray());

TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ks);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .hostnameVerifier(hostnameVerifier)
        .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) tmf.getTrustManagers()[0])
        .readTimeout(1, TimeUnit.MINUTES) // important for HTTP long-polling
        .build();

IO.Options options = new IO.Options();
options.callFactory = okHttpClient;
options.webSocketFactory = okHttpClient;

Socket socket = IO.socket(URI.create("https://example.com"), options);

Trust all certificates

Please use with caution, as this defeats the whole purpose of using secure connections.

This is equivalent to rejectUnauthorized: false for the JavaScript client.

HostnameVerifier hostnameVerifier = new HostnameVerifier() {
    @Override
    public boolean verify(String hostname, SSLSession sslSession) {
        return true;
    }
};

X509TrustManager trustManager = new X509TrustManager() {
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[] {};
    }

    @Override
    public void checkClientTrusted(X509Certificate[] arg0, String arg1) {
        // not implemented
    }

    @Override
    public void checkServerTrusted(X509Certificate[] arg0, String arg1) {
        // not implemented
    }
};

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { trustManager }, null);

OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .hostnameVerifier(hostnameVerifier)
        .sslSocketFactory(sslContext.getSocketFactory(), trustManager)
        .readTimeout(1, TimeUnit.MINUTES) // important for HTTP long-polling
        .build();

IO.Options options = new IO.Options();
options.callFactory = okHttpClient;
options.webSocketFactory = okHttpClient;

Socket socket = IO.socket(URI.create("https://example.com"), options);

Multiplexing

The Java client does support multiplexing: this allows to split the logic of your application into distinct modules, while using one single WebSocket connection to the server.

Reference: https://socket.io/docs/v4/namespaces/

Socket socket = IO.socket(URI.create("https://example.com")); // the main namespace
Socket productSocket = IO.socket(URI.create("https://example.com/product")); // the "product" namespace
Socket orderSocket = IO.socket(URI.create("https://example.com/order")); // the "order" namespace

// all 3 sockets share the same Manager
System.out.println(socket.io() == productSocket.io()); // true
System.out.println(socket.io() == orderSocket.io()); // true

Please note that multiplexing will be disabled in the following cases:

  • multiple creation for the same namespace
Socket socket = IO.socket(URI.create("https://example.com"));
Socket socket2 = IO.socket(URI.create("https://example.com"));

System.out.println(socket.io() == socket2.io()); // false
  • different domains
Socket socket = IO.socket(URI.create("https://first.example.com"));
Socket socket2 = IO.socket(URI.create("https://second.example.com"));

System.out.println(socket.io() == socket2.io()); // false
  • usage of the forceNew option
IO.Options options = IO.Options.builder()
    .setForceNew(true)
    .build();

Socket socket = IO.socket(URI.create("https://example.com"));
Socket socket2 = IO.socket(URI.create("https://example.com/admin"), options);

System.out.println(socket.io() == socket2.io()); // false

2 ответы

Из вашего кода

var socket = new io.Socket('uwtech.nodester.com',{'port':80,'transports':'xhr-multipart'});

Попробуйте добавить еще транспорты

Доступность протокола Xhr-multipart проверяется строкой:

'XMLHttpRequest' in window && 'prototype' in XMLHttpRequest && 'multipart' in XMLHttpRequest.prototype

попробуйте зарегистрировать его результат.

ответ дан 19 апр.

Вы уверены, что правильно указываете транспорты? Ошибка, которую вы получаете, возникает только тогда, когда socket.io не может найти ни одного перечисленного транспорта.

if (!this.transport && 'console' in window) console.error('No transport available');

Попробуйте сделать что-то вроде этого … (без указания транспорта)

var socket= new io.Socket('yourhost.com')

и посмотрите, остались ли у вас проблемы

ответ дан 19 апр.

Не тот ответ, который вы ищете? Просмотрите другие вопросы с метками

node.js
socket.io

or задайте свой вопрос.

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Socket init error
  • Socket error что означает
  • Socket error скачать
  • Socket error the remote host closed the connection nbminer ошибка
  • Socket error resource temporarily unavailable

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии