socket.io-client
socket.io-client copied to clipboard
NWJS socket.io-client with forceNode not work
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
- socket.io version: [email protected]
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 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
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!