Socket.io-client: Unrecognized WebSocket connection option(s) `agent`, `perMessageDeflate`, `pfx`, `key`, `passphrase`, `cert`, `ca`, `ciphers`, `rejectUnauthorized`. Did you mean to put these under `headers`?

Created on 15 Apr 2019  ·  49Comments  ·  Source: socketio/socket.io-client

You want to:

  • [x] report a bug
  • [ ] request a feature

Current behaviour

When I install socket.io-client on a blank React Native Expo project I have a yellow message with:

Unrecognized WebSocket connection option(s) `agent`, `perMessageDeflate`, `pfx`, `key`, `passphrase`, `cert`, `ca`, `ciphers`, `rejectUnauthorized`. Did you mean to put these under `headers`?

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

yarn add socket.io-client

In App.js in the React Native project:

import React from 'react';
import { YellowBox } from 'react-native';
import io from 'socket.io-client';

YellowBox.ignoreWarnings(['Remote debugger']);

import AppContainer from './config/routing';

export default class App extends React.Component {
    constructor(props) {
        super(props);
    }

    componentWillMount() {
        const socket = io('http://10.0.60.26:3000', {
            forceNew: true
        });
        socket.on('connect', () => console.log('Connection'));
    }

    render() {
        return <AppContainer />;
    }
}
bug

Most helpful comment

For me it worked when I downgraded to 2.1.1 I did:
yarn add [email protected]

At first it didn't work because I was adding the ^ symbol before the version socket.io-client@^2.1.1 which I believe accepts other minor versions of the package.

All 49 comments

Same problem :(

+1

+1

+1

Seems to have been an issue since at least as far back as Dec 18

+1

+1

+1

+1

I am still getting this warning when using socket.io (2.2.0) on React-Native. I can silence the yellow box on the device screen with:

import { YellowBox } from 'react-native'

YellowBox.ignoreWarnings([
  'Unrecognized WebSocket connection option(s) `agent`, `perMessageDeflate`, `pfx`, `key`, `passphrase`, `cert`, `ca`, `ciphers`, `rejectUnauthorized`. Did you mean to put these under `headers`?'
])

but I still get this annoying warning on the console...

downgrade to "socket.io-client": "2.1.0" and all OK

For me it worked when I downgraded to 2.1.1 I did:
yarn add [email protected]

At first it didn't work because I was adding the ^ symbol before the version socket.io-client@^2.1.1 which I believe accepts other minor versions of the package.

Still an issue @2.2.0

Try downgrading socket.io-client to 1.7.2, it works for me.

Still an issue @^2.3.0

Still an issue v2.3.0 with react-native

@2.1.1 is OK. But 2.3.0 throws the warning message on RN 0.61.1

any solution till now

Still an issue v2.3.0 with react-native

Hey guys! We have fixed this issue by downgrading to v2.1.1

Make sure you completely remove the older version and clear the cache.

  1. remove socket.io-client from package.json & better delete your package-lock/yarn.lock files.
  2. delete your entire node_modules folder (start fresh)
  3. npm install socket.[email protected] --save

Done! This should work with react-native & react-native-web!

I have this same issue with react-native: 0.61.4 but somehow the app is crashing, I don't know if it's happening because of the warning or if is another socket-related thing, but when I tried to connect to the socket the app closes.

This is my conf:
{ autoConnect: false, reconnectionDelay: 1000, reconnection: true, transports: ['websocket'], agent: false, // [2] Please don't set this to true upgrade: false, rejectUnauthorized: false }

Does socket.open crashes if the socket is already connected?

This warning is raised here by ReactNative/WebSocket.js:117 because EngineIO (used by SocketIO under the hood) will reference the exposed ReactNative WebSocket implementation via EngineIO/websocket.js:121 which is passed opts which contains the properties that the warning message mentions. Curiously enough, these added properties described by the EngineIO maintainers via comment are "SSL options for Node.js client".

By inserting something like the code below at EngineIO/websocket.js:114 to manipulate the opts given to the WebSocket constructor we remove all the extraneous keys in opts to successfully stop the warning from appearing in the first place (omit is imported from Lodash, can be reworked out).

// lib/transports/websocket.js
...
if (this.isReactNative) {
  // prettier-ignore
  opts = omit(opts, ['agent', 'perMessageDeflate', 'pfx', 'key', 'passphrase', 'cert', 'ca', 'ciphers', 'rejectUnauthorized']);
}
...

If you're looking for a solution that doesn't involve simply muting the warning via YellowBox.ignoreWarnings then you could completely override the doOpen as defined EngineIO/websocket.js:87 by adding something like this below, to the entry point of your ReactNative project, typically index.js.

// index.js
...
+ import 'patches/EngineIOHeaderWarning';
...
// patches/EngineIOHeaderWarning.js
const WS = require('engine.io-client/lib/transports/websocket');

var WebSocketImpl = WebSocket; // eslint-disable-line no-undef

WS.prototype.doOpen = function() {
  if (!this.check()) {
    // let probe timeout
    return;
  }

  var uri = this.uri();
  var protocols = this.protocols;
  var opts = {};

  if (this.extraHeaders) {
    opts.headers = this.extraHeaders;
  }
  if (this.localAddress) {
    opts.localAddress = this.localAddress;
  }

  try {
    this.ws = new WebSocketImpl(uri, protocols, opts);
  } catch (err) {
    return this.emit('error', err);
  }
};

Overall, if we create a pull request for EngineIO to exclude these extra opts that aren't needed when used in ReactNative via this.isReactNative then we could suppress this warning for all using the SocketIO Client in their ReactNative projects.

You want to:

  • [x] report a _bug_
  • [ ] request a _feature_

Current behaviour

When I install socket.io-client on a blank React Native Expo project I have a yellow message with:

Unrecognized WebSocket connection option(s) `agent`, `perMessageDeflate`, `pfx`, `key`, `passphrase`, `cert`, `ca`, `ciphers`, `rejectUnauthorized`. Did you mean to put these under `headers`?

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

yarn add socket.io-client

In App.js in the React Native project:

import React from 'react';
import { YellowBox } from 'react-native';
import io from 'socket.io-client';

YellowBox.ignoreWarnings(['Remote debugger']);

import AppContainer from './config/routing';

export default class App extends React.Component {
    constructor(props) {
        super(props);
    }

    componentWillMount() {
        const socket = io('http://10.0.60.26:3000', {
            forceNew: true
        });
        socket.on('connect', () => console.log('Connection'));
    }

    render() {
        return <AppContainer />;
    }
}

My Solution:

Just save the socket in a useState like this:

import io from 'socket.io-client';
// ...

const [socket] = useState(() => io('SERVER_URL'));

Problem solved.

In my case, v2.3 is ok when I connect to the local socket.io server.
But it occurs errors when I connect to the remote socket.io server.
The server source is the same.
So I downgrade the socket.io client version to 2.1.1, and it works fine.

This warning is raised here by ReactNative/WebSocket.js:117 because EngineIO (used by SocketIO under the hood) will reference the exposed ReactNative WebSocket implementation via EngineIO/websocket.js:121 which is passed opts which contains the properties that the warning message mentions. Curiously enough, these added properties described by the EngineIO maintainers via comment are "SSL options for Node.js client".

By inserting something like the code below at EngineIO/websocket.js:114 to manipulate the opts given to the WebSocket constructor we remove all the extraneous keys in opts to successfully stop the warning from appearing in the first place (omit is imported from Lodash, can be reworked out).

// lib/transports/websocket.js
...
if (this.isReactNative) {
  // prettier-ignore
  opts = omit(opts, ['agent', 'perMessageDeflate', 'pfx', 'key', 'passphrase', 'cert', 'ca', 'ciphers', 'rejectUnauthorized']);
}
...

If you're looking for a solution that doesn't involve simply muting the warning via YellowBox.ignoreWarnings then you could completely override the doOpen as defined EngineIO/websocket.js:87 by adding something like this below, to the entry point of your ReactNative project, typically index.js.

// index.js
...
+ import 'patches/EngineIOHeaderWarning';
...
// patches/EngineIOHeaderWarning.js
const WS = require('engine.io-client/lib/transports/websocket');

var WebSocketImpl = WebSocket; // eslint-disable-line no-undef

WS.prototype.doOpen = function() {
  if (!this.check()) {
    // let probe timeout
    return;
  }

  var uri = this.uri();
  var protocols = this.protocols;
  var opts = {};

  if (this.extraHeaders) {
    opts.headers = this.extraHeaders;
  }
  if (this.localAddress) {
    opts.localAddress = this.localAddress;
  }

  try {
    this.ws = new WebSocketImpl(uri, protocols, opts);
  } catch (err) {
    return this.emit('error', err);
  }
};

Overall, if we create a pull request for EngineIO to exclude these extra opts that aren't needed when used in ReactNative via this.isReactNative then we could suppress this warning for all using the SocketIO Client in their ReactNative projects.

Your code wouldn't allow me to connect to the server and changed the intended behaviour of EngineIO so I've just wrapped those options in an if statement but used the same patch mechanism you suggested

// patches/EngineIOHeaderWarning.js
const WS = require('engine.io-client/lib/transports/websocket');

var WebSocketImpl = WebSocket; // eslint-disable-line no-undef

WS.prototype.doOpen = function() {
    if (!this.check()) {
        // let probe timeout
        return;
    }

    var uri = this.uri();
    var protocols = this.protocols;
    var opts = {};

    if(!this.isReactNative){
        opts.agent = this.agent;
        opts.perMessageDeflate = this.perMessageDeflate;

        // SSL options for Node.js client
        opts.pfx = this.pfx;
        opts.key = this.key;
        opts.passphrase = this.passphrase;
        opts.cert = this.cert;
        opts.ca = this.ca;
        opts.ciphers = this.ciphers;
        opts.rejectUnauthorized = this.rejectUnauthorized;
    }


    if (this.extraHeaders) {
        opts.headers = this.extraHeaders;
    }
    if (this.localAddress) {
        opts.localAddress = this.localAddress;
    }

    try {
        this.ws =
            this.usingBrowserWebSocket && !this.isReactNative
                ? protocols
                ? new WebSocketImpl(uri, protocols)
                : new WebSocketImpl(uri)
                : new WebSocketImpl(uri, protocols, opts);
    } catch (err) {
        return this.emit('error', err);
    }

    if (this.ws.binaryType === undefined) {
        this.supportsBinary = false;
    }

    if (this.ws.supports && this.ws.supports.binary) {
        this.supportsBinary = true;
        this.ws.binaryType = 'nodebuffer';
    } else {
        this.ws.binaryType = 'arraybuffer';
    }

    this.addEventListeners();
};

downgrade to "socket.io-client": "2.1.0" and all OK

This worked for me.

If I well understand the issue, is this a related dependencies issue introduce in https://github.com/socketio/socket.io-client/commit/06e9a4ca2621176c30c352b2ba8b34fa42b8d0ba?

The downgrade to 2.1.1 works indeed, but we are stuck on a two years old releases.

Can @ptboyer be applied and release on the project?

Does this warning affect the functionality of the package? Just setting it up and don't want to be held back by this. Happy to ignore if it has no other consequences

Edit: For anyone wondering the same thing. As far as I can tell this warning is inconsequential.

@schumannd This issue is purely about muting the error/warning message. Functionally, this warning is inconsequential. :)

+1

I am very worried about if the socket.io library is still maintained or not because of no official reply about a fix or an upcoming update.

+1

+1

const _io = ioClient.connect(socketurl, { forceNode: true });
It's work

@isthaison It doesn't work for me

@isthaison for me it works... but every other http request becomes very slow... I don't know how it's related to the workaround... but it is...

{ forceNode: true }

Thank you. this work for me.

This is the only solution that worked for me.

This warning is raised here by ReactNative/WebSocket.js:117 because EngineIO (used by SocketIO under the hood) will reference the exposed ReactNative WebSocket implementation via EngineIO/websocket.js:121 which is passed opts which contains the properties that the warning message mentions. Curiously enough, these added properties described by the EngineIO maintainers via comment are "SSL options for Node.js client".
By inserting something like the code below at EngineIO/websocket.js:114 to manipulate the opts given to the WebSocket constructor we remove all the extraneous keys in opts to successfully stop the warning from appearing in the first place (omit is imported from Lodash, can be reworked out).

// lib/transports/websocket.js
...
if (this.isReactNative) {
  // prettier-ignore
  opts = omit(opts, ['agent', 'perMessageDeflate', 'pfx', 'key', 'passphrase', 'cert', 'ca', 'ciphers', 'rejectUnauthorized']);
}
...

If you're looking for a solution that doesn't involve simply muting the warning via YellowBox.ignoreWarnings then you could completely override the doOpen as defined EngineIO/websocket.js:87 by adding something like this below, to the entry point of your ReactNative project, typically index.js.

// index.js
...
+ import 'patches/EngineIOHeaderWarning';
...
// patches/EngineIOHeaderWarning.js
const WS = require('engine.io-client/lib/transports/websocket');

var WebSocketImpl = WebSocket; // eslint-disable-line no-undef

WS.prototype.doOpen = function() {
  if (!this.check()) {
    // let probe timeout
    return;
  }

  var uri = this.uri();
  var protocols = this.protocols;
  var opts = {};

  if (this.extraHeaders) {
    opts.headers = this.extraHeaders;
  }
  if (this.localAddress) {
    opts.localAddress = this.localAddress;
  }

  try {
    this.ws = new WebSocketImpl(uri, protocols, opts);
  } catch (err) {
    return this.emit('error', err);
  }
};

Overall, if we create a pull request for EngineIO to exclude these extra opts that aren't needed when used in ReactNative via this.isReactNative then we could suppress this warning for all using the SocketIO Client in their ReactNative projects.

Your code wouldn't allow me to connect to the server and changed the intended behaviour of EngineIO so I've just wrapped those options in an if statement but used the same patch mechanism you suggested

// patches/EngineIOHeaderWarning.js
const WS = require('engine.io-client/lib/transports/websocket');

var WebSocketImpl = WebSocket; // eslint-disable-line no-undef

WS.prototype.doOpen = function() {
    if (!this.check()) {
        // let probe timeout
        return;
    }

    var uri = this.uri();
    var protocols = this.protocols;
    var opts = {};

    if(!this.isReactNative){
        opts.agent = this.agent;
        opts.perMessageDeflate = this.perMessageDeflate;

        // SSL options for Node.js client
        opts.pfx = this.pfx;
        opts.key = this.key;
        opts.passphrase = this.passphrase;
        opts.cert = this.cert;
        opts.ca = this.ca;
        opts.ciphers = this.ciphers;
        opts.rejectUnauthorized = this.rejectUnauthorized;
    }


    if (this.extraHeaders) {
        opts.headers = this.extraHeaders;
    }
    if (this.localAddress) {
        opts.localAddress = this.localAddress;
    }

    try {
        this.ws =
            this.usingBrowserWebSocket && !this.isReactNative
                ? protocols
                ? new WebSocketImpl(uri, protocols)
                : new WebSocketImpl(uri)
                : new WebSocketImpl(uri, protocols, opts);
    } catch (err) {
        return this.emit('error', err);
    }

    if (this.ws.binaryType === undefined) {
        this.supportsBinary = false;
    }

    if (this.ws.supports && this.ws.supports.binary) {
        this.supportsBinary = true;
        this.ws.binaryType = 'nodebuffer';
    } else {
        this.ws.binaryType = 'arraybuffer';
    }

    this.addEventListeners();
};

const _io = ioClient.connect(socketurl, { forceNode: true });
It's work

It works with me, Thanks!

"socket.io-client": "^2.3.0"

const socket = io(host, { forceNode: true });

const _io = ioClient.connect(socketurl, { forceNode: true });
It's work

It works with me, Thanks!

"socket.io-client": "^2.3.0"

const socket = io(host, { forceNode: true });

It worked for me too! Big thanks

You can simply add some headers and it works!
socket = io.connect('SOCKET_URL_HERE', { jsonp: false, agent: '-', pfx: '-', cert: '-', ca: '-', ciphers: '-', rejectUnauthorized: '-', perMessageDeflate: '-' });

const _io = ioClient.connect(socketurl, { forceNode: true });

This resolves the warning but makes my socket connection really really slow(timeout actually), so its unusable for me.

const _io = ioClient.connect(socketurl, { forceNode: true });

This resolves the warning but makes my socket connection really really slow(timeout actually), so its unusable for me.

same here: connection timeout!

I got rid of froceNode and downgraded to 2.1.0 and it worked fine. I also had the issue where I was using localhost and not the IP to my emulator device.

The same @SaveYourTime , I'm using "socket.io-client": "^2.3.0"
refer here https://socket.io/docs/client-api/.
I why add forceNode option

This issue should be fixed on engine.io-client v3.4.3 so all you need to do is to delete the yarn.lock file and the node_modules directory then run yarn install

ref https://github.com/socketio/engine.io-client/commit/2f5c948abe8fd1c0fdb010e88f96bd933a3792ea

@BassemN Perhaps instead of deleting your yarn.lock file, you could use yarn upgrade-interactive to bump the version safely?

It seems a bit counter-intuitive to the idea of a "lock" file if you completely destroy it every time you want to upgrade your packages. 😅

It should be fixed by https://github.com/socketio/engine.io-client/commit/e5bc1063cc90a7b6262146c7b5338ffff1ff9e5b (included in [email protected] and [email protected]).

Regarding the forceNode option, it seems React Native actually supports WebSocket (ref), so forceNode: true should not be needed. Isn't that the case?

Was this page helpful?
0 / 5 - 0 ratings