socket.io-client: XHR Polling Error appears when debugger is present

You want to:

  • report a bug
  • request a feature

Current behavior

I am experiencing trouble trying to make a web socket connection on react-native. I am not sure if this platform is supported or not, however, this error is reproducible on a regular node.js app. Strangely enough I only have trouble when react-native’s built in debugger is disabled. I am testing this on IOS 10.2 with react-native v0.43.1 and socket.io-client v1.7.3. My server is running socket.io v1.7.2 hosted on HTTP port 1337.

Steps to reproduce (if the current behaviour is a bug)

As soon as I implement socket.io-client in react-native and attempt a connection without the debugger enabled, it should reproduce with two errors based on the options. If I do not specify my transports option then the error would be XHR: POLLING ERROR. If I specify ‘websocket’ in my transports option then the error would become WEBSOCKET ERROR. Thats all I get.

Expected behavior

Regular web socket connection to my server. It works with the debugger enabled.

Setup

  • OS: OSX El Capitan 10.11.6
  • browser: I believe react-native uses webkit, however i am not sure.
  • socket.io version: stated above

Other information (e.g. stacktraces, related issues, suggestions how to fix)

The only other issue I found related to this one was #1056 and I am surprised about how oddly related these issues are. I have retried the scenario on a regular node.js app and I experienced similar outcomes, however the errors were more detailed as shown below.

Without a specified transports option:

{ Error: xhr poll error
    at XHR.Transport.onError (/path/to/root/node_modules/engine.io-client/lib/transport.js:64:13)
    at Request.<anonymous> (/path/to/root/node_modules/engine.io-client/lib/transports/polling-xhr.js:129:10)
    at Request.Emitter.emit (/path/to/root/node_modules/component-emitter/index.js:133:20)
    at Request.onError (/path/to/root/node_modules/engine.io-client/lib/transports/polling-xhr.js:307:8)
    at Timeout._onTimeout (/path/to/root/node_modules/engine.io-client/lib/transports/polling-xhr.js:254:18)
    at ontimeout (timers.js:365:14)
    at tryOnTimeout (timers.js:237:5)
    at Timer.listOnTimeout (timers.js:207:5) type: 'TransportError', description: 503 }

With transports: ['websocket']:

{ Error: websocket error
    at WS.Transport.onError (/path/to/root/node_modules/engine.io-client/lib/transport.js:64:13)
    at WebSocket.ws.onerror (/path/to/root/node_modules/engine.io-client/lib/transports/websocket.js:149:10)
    at WebSocket.onError (/path/to/root/node_modules/ws/lib/WebSocket.js:452:14)
    at emitOne (events.js:96:13)
    at WebSocket.emit (events.js:189:7)
    at ClientRequest.onerror (/path/to/root/node_modules/ws/lib/WebSocket.js:711:10)
    at emitOne (events.js:96:13)
    at ClientRequest.emit (events.js:189:7)
    at TLSSocket.socketErrorListener (_http_client.js:358:9)
    at emitOne (events.js:96:13)
  type: 'TransportError',
  description: 
   { Error: socket hang up
       at TLSSocket.onHangUp (_tls_wrap.js:1117:19)
       at Object.onceWrapper (events.js:291:19)
       at emitNone (events.js:91:20)
       at TLSSocket.emit (events.js:186:7)
       at endReadableNT (_stream_readable.js:974:12)
       at _combinedTickCallback (internal/process/next_tick.js:74:11)
       at process._tickCallback (internal/process/next_tick.js:98:9)
     code: 'ECONNRESET',
     type: 'error',
     target: 
      WebSocket {
        domain: null,
        _events: [Object],
        _eventsCount: 4,
        _maxListeners: undefined,
        _socket: null,
        _ultron: null,
        _closeReceived: false,
        bytesReceived: 0,
        readyState: 0,
        supports: [Object],
        extensions: {},
        _binaryType: 'nodebuffer',
        _isServer: false,
        url: 'wss://SERVER_IP:1337/socket.io/?EIO=3&transport=websocket',
        protocolVersion: 13 } } }

Also keep in mind, socket.io’s browser-based client works flawlessly connecting to this specific web server.

I have tried various different networks, ISP’s, and even VPN’s. I am clueless at this point.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 33
  • Comments: 33 (2 by maintainers)

Commits related to this issue

Most upvoted comments

I’ve solved my problem a week ago by refactoring but I don’t remember what exactly solved the problem. Sorry for that, I had a busy week and that was the initial commit.

You can try setting opts.transports to only websocket in client:

io.connect(url, { transports: ['websocket'] }); // default is ['polling', 'websocket']

I had too complicated socket and action binding logic before I refactored the code. So make sure your socket logic in your code is working and make it simpler to debug.

try this

require('socket.io-client')('http://localhost', {
  rejectUnauthorized:   false,
})

For future readers:

Please check the documentation here: https://socket.io/docs/v3/client-initialization/#Options

I’ve had this issue and I spent 2 hours on this, turns out it’s just specifying your options correctly. Here is how you should specify them :

   let socketClient = socketIOClient.connect(`http://localhost:3001`,{ // [1] Important as fuck 
      reconnectionDelay: 1000,
      reconnection:true,
      reconnectionAttempts: 10,
      transports: ['websocket'],
      agent: false, // [2] Please don't set this to true
      upgrade: false,
      rejectUnauthorized: false
   });

[1] If you don’t specify whether to use http or https , it defaults to https . Or if you dont specify the port right after the url as “url.com:port” it defaults to 80 or 443 depending on the protocol. I’ve seen some stackoverflow answers that have port specified as an option in the options object. I’ve looked into the code and there is no such option. You need to include the port in the url.

[2] And also, I set the agent to true and it failed to establish a ws connection and there was no error, it simply timed out. Just don’t specify the agent at all. It defaults to false.

Hi! i had the same problem while i was trying to connect from a Node.js app to the server, here’s my code:

const socket = require('socket.io-client')('https://domain.com')

The log that i got running DEBUG=engine* npm run dev was some like this:

asciicast

engine.io-client:socket creating transport "polling" +2s
engine.io-client:polling polling +1ms
engine.io-client:polling-xhr xhr poll +0ms
engine.io-client:polling-xhr xhr open GET: https://domain.com/socket.io/?EIO=3&transport=polling&t=LzBM71r&b64=1 +0ms
engine.io-client:polling-xhr xhr data null +0ms
engine.io-client:socket setting transport polling +1ms
engine.io-client:socket socket error {"type":"TransportError","description":503} +7ms
engine.io-client:socket socket close with reason: "transport error" +0ms
engine.io-client:polling transport not open - deferring close +0ms

When i tried connect from a browser to https://domain.com/socket.io/socket.io.js it worked and using io('https://domain.com') too, so i followed the instructions in the comments and i changed my code to:

const socket = require('socket.io-client')('https://domain.com', { rejectUnauthorized: false })

And it worked, but it’s weird, i have valid certs from Let’s Encrypt, or it’s normal? anyway… i added the transports option (from the comments too) for avoiding other connections than websocket and at the end the code was:

const socket = require('socket.io-client')('https://domain.com', {
  transports: ['websocket'],
  rejectUnauthorized: false
})

Thanks @ibrahimduran and @SupremeTechnopriest 😄

My apologies if i wrote like Tarzan 😅 i working on my english haha

I have the same issue. Then I change my client code to

require('socket.io-client')('wss://myserver:port/ws', { transports: ['websocket'], rejectUnauthorized: false });

But now, I get a 404 error response. The log show that there is an additional /socket.io/ added to my request url.

 { Error: unexpected server response (404)
       at ClientRequest._req.on (/Users/chris/Projects/nationsky/mgmt-server/backend/node_modules/ws/lib/WebSocket.js:650:26)
       at emitOne (events.js:115:13)
       at ClientRequest.emit (events.js:210:7)
       at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:564:21)
       at HTTPParser.parserOnHeadersComplete (_http_common.js:116:23)
       at TLSSocket.socketOnData (_http_client.js:453:20)
       at emitOne (events.js:115:13)
       at TLSSocket.emit (events.js:210:7)
       at addChunk (_stream_readable.js:252:12)
       at readableAddChunk (_stream_readable.js:239:11)
     type: 'error',
     target:
      WebSocket {
        domain: null,
        _events: [Object],
        _eventsCount: 4,
        _maxListeners: undefined,
        readyState: 0,
        bytesReceived: 0,
        extensions: {},
        protocol: '',
        _binaryType: 'arraybuffer',
        _finalize: [Function: bound finalize],
        _finalizeCalled: false,
        _closeMessage: null,
        _closeTimer: null,
        _closeCode: null,
        _receiver: null,
        _sender: null,
        _socket: null,
        _ultron: null,
        protocolVersion: 13,
        _isServer: false,
        url: 'wss://myserver:port/socket.io/?access_token=HnbtDUEWu1i1HVrAn-DO9YOL6GZxoittWAf8Sz_RR0s&EIO=3&transport=websocket',
        _req: [Object] } } }

I know this solution is going to sound a bit odd, but I got here by googling this error.

In my case I was getting this because my server wasn’t running (I thought it was). Hope that helps someone else 😃

Hi all. So I’m using PM2 cluster for my node express server and using redis adapter:

const redis = require('socket.io-redis') 
io.adapter(redis(config.redis))

For browser clients this seems fine, but for socket.io-client I get:

{ Error: xhr post error
    at XHR.Transport.onError (/home/user/Desktop/nodeclienttest/node_modules/engine.io-client/lib/transport.js:67:13)
    at Request.<anonymous> (/home/user/Desktop/nodeclienttest/node_modules/engine.io-client/lib/transports/polling-xhr.js:111:10)
    at Request.Emitter.emit (/home/user/Desktop/nodeclienttest/node_modules/component-emitter/index.js:133:20)
    at Request.onError (/home/user/Desktop/nodeclienttest/node_modules/engine.io-client/lib/transports/polling-xhr.js:311:8)
    at Timeout._onTimeout (/home/user/Desktop/nodeclienttest/node_modules/engine.io-client/lib/transports/polling-xhr.js:258:18)
    at listOnTimeout (timers.js:327:15)
    at processTimers (timers.js:271:5) type: 'TransportError', description: 400 }
{ Error: xhr poll error
    at XHR.Transport.onError (/home/user/Desktop/nodeclienttest/node_modules/engine.io-client/lib/transport.js:67:13)
    at Request.<anonymous> (/home/user/Desktop/nodeclienttest/node_modules/engine.io-client/lib/transports/polling-xhr.js:130:10)
    at Request.Emitter.emit (/home/user/Desktop/nodeclienttest/node_modules/component-emitter/index.js:133:20)
    at Request.onError (/home/user/Desktop/nodeclienttest/node_modules/engine.io-client/lib/transports/polling-xhr.js:311:8)
    at Timeout._onTimeout (/home/user/Desktop/nodeclienttest/node_modules/engine.io-client/lib/transports/polling-xhr.js:258:18)
    at listOnTimeout (timers.js:327:15)
    at processTimers (timers.js:271:5) type: 'TransportError', description: 400 }

If I change client code to use websocket transport it all works fine.

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

The problem is I don’t want to require this code change to all client code.

My recommendation is to change socket.io-client to attempt websocket transport if xhr polling transport is failing. What do you think?

Yes I down version from 2.0.1 to 1.7.4 fix this

I’ll try the we transport. For now I’ve downgraded to 1.7.4 and all seems to work.