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`?

You want to:

  • 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 />;
    }
}

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 53
  • Comments: 50 (1 by maintainers)

Commits related to this issue

Most upvoted comments

For me it worked when I downgraded to 2.1.1 I did: yarn add socket.io-client@2.1.1

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.

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

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…

Still an issue @^2.3.0

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.io-client@2.1.1 --save

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

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.

Still an issue @2.2.0

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 });

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.

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();
};

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 }); 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

Proxying WebSockets is working for me. I am using node HTTP-proxy to allow ‘ws’ on the local machine, on a remote server configured Nginx proxy.

Server Side: const io = require(“socket.io”)(server.listener, { log: true, pingInterval: 60000, pingTimeout: 600000, cors: { origin: “http://localhost:3000”, methods: [“GET”, “POST”] } }); const proxy = HttpProxy.createProxyServer({ ws: true }); io.on(“upgrade”, function(req, socket, head) { proxy.ws(req, socket, head); });

Front Side: import {Manager} from “socket.io-client”; socketInstance = new Manager(‘ws://localhost:1342/’, { transports: [“websocket”] , protocols:[“http”], port:1342, auth:{ token: xxxxxx} });

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

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.

{ forceNode: true }

Thank you. this work for me.

@isthaison It doesn’t work for me

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