socket.io-client icon indicating copy to clipboard operation
socket.io-client copied to clipboard

NWJS socket.io-client with forceNode not work

Open LabDeve opened this issue 6 years ago • 2 comments

You want to:

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

Current behaviour

I'm trying to use socket.io-client within an nwJS app. Now, I need to use the proxy configuration (agent option) and I realized that I need to also set the "forceNode" option. But it doesn't work, the connection times out ... If I use the external ws module it works (requires ('ws')).

With a little debug, I can see that here:

WS.prototype.check = function () {
  return !!WebSocketImpl && !('__initialize' in WebSocketImpl && this.name === WS.prototype.name);
};

WebSocketImpl is undefined. What could be the problem?

Thanks

Setup

LabDeve avatar Jun 26 '19 10:06 LabDeve

Ok, I have investigated a bit inside the sources and I found that, inside "engine.io-client/lib/transports/websocket.js", the "ws" module will never be imported (inside a node context of NWJS):

var BrowserWebSocket, NodeWebSocket;

if (typeof WebSocket !== 'undefined') {
  BrowserWebSocket = WebSocket;
} else if (typeof self !== 'undefined') {
  BrowserWebSocket = self.WebSocket || self.MozWebSocket;
} else {
  try {
    NodeWebSocket = require('ws');
  } catch (e) { }
}

...



I think this piece of code is slightly wrong, and should be written in some way like this:

var BrowserWebSocket, NodeWebSocket;

if (typeof WebSocket !== 'undefined') {
  BrowserWebSocket = WebSocket;
} else if (typeof self !== 'undefined') {
  BrowserWebSocket = self.WebSocket || self.MozWebSocket;
}

try {
  NodeWebSocket = require('ws');
} catch (e) { }

or like this:

var BrowserWebSocket, NodeWebSocket;
var isNode = new Function("try {return this===global;}catch(e){return false;}")();

if (typeof WebSocket !== 'undefined') {
  BrowserWebSocket = WebSocket;
} else if (typeof self !== 'undefined') {
  BrowserWebSocket = self.WebSocket || self.MozWebSocket;
}

if (isNode) {
  try {
    NodeWebSocket = require('ws');
  } catch (e) { }
}

so that when needed "NodeWebSocket" will be available.

doppiaQ avatar Jun 27 '19 08:06 doppiaQ

@doppiaQ Thank you so much!

for now, waiting for an official fix, I wrote a small patch to temporarily solve the problem for anyone who needs it:

fix_engine_io_node_websocket.js

const fs = require("fs");
const path = require("path");

const filePath = (process.argv[2] || './node_modules') + '/engine.io-client/lib/transports/websocket.js';

let file = fs.readFileSync(filePath, 'utf8');

if (file.indexOf('* BUGFIX NODE CONTEXT') < 0) {
    file = file.replace('var BrowserWebSocket, NodeWebSocket;', `
var BrowserWebSocket, NodeWebSocket;

/*************************
 * BUGFIX NODE CONTEXT
 ************************/
var isNode = new Function("try {return this===global;}catch(e){return false;}")();
if (isNode) {
  try {
    NodeWebSocket = require('ws');
  } catch (e) { }
}
/************************/
`)   
    fs.writeFileSync(filePath, file, 'utf8'); 

    console.log('[fix_engine_io_node_websocket] websocket.js successful fixed!')
}else{
    console.log('[fix_engine_io_node_websocket] Nothing to fix! Bye')
}

then in the project root run: node fix_engine_io_node_websocket.js

LabDeve avatar Jun 27 '19 09:06 LabDeve

For future readers:

This issue was fixed in https://github.com/socketio/engine.io-client/commit/3f3a6f991404ef601252193382d2d2029cff6c45. The forceNode option is no longer needed.

We've added a guide to use Socket.IO with NW.js: https://socket.io/how-to/use-with-nwjs

Have a great day!

darrachequesne avatar Apr 12 '24 09:04 darrachequesne