Node JS: net.Socket is not a constructor - node.js

The below code works fine if I run it from my command line, but if I run this code anywhere in my project I get this error:
net.Socket is not a constructor
I've tried making the below code an object and importing / requiring it into my project and I still get that error.
var net = require('net');
var client = new net.Socket();
client.connect(3000, '127.0.0.1', function() {
console.log('Connected');
client.write('Hello, server! Love, Client.');
});
Am I miss understanding what require does, I also tried using import and import * as to obtain 'net'.
I'm not too sure what information would be useful in the situation. Any suggestions would be great.

There are no plain TCP sockets in the browser, so that is why trying to use net.Socket in the browser (via webpack, browserify, etc.) won't work.
There could be a "polyfill" of sorts that requires a server to make the TCP connection on the browser's behalf though (or perhaps via some bridge to a Flash or Java applet).

use node 16 version.
these features are currently under Node.js v16.9.1
https://nodejs.org/dist/latest-v16.x/docs/api/net.html

Related

Connect to a socket.io server from a Node.js server using the 'ws' package

I have a Node.js server which utilizes the popular ws package for using web sockets. I'd like to use this library to connect to an third party server which is running socket.io.
If I were to use socket.io on my server, the connection code would be something like this:
const socket = socketIo('https://api.example.com/1.0/scores')
I've attempted to connect to the same service using the ws package, and modifying the url:
const wsClient = new WebSocket('wss://api.example.com/1.0/scores');
but this results in the following:
Error: Unexpected server response: 200
Question:
What needs to be done to connect to a third party server running socket.io from a server running the ws package?
Additional Info:
I've noticed in my searches that some people have suggested appending
/socket.io/?EIO=3&transport=websocket to the end of the url. This
does not throw the same error as above (> Error: Unexpected server
response: 200) nor throw any visible error, but does not appear to
work (no data is received from the remote server).
Using new WebSocket('ws://api.example.com/1.0/scores?EIO=3&transport=websocket'); to open the connection (via ws) results in the following stack trace:
{ Error: Parse Error
at Socket.socketOnData
at emitOne
at Socket.emit
// ...
}
The socket.io api utilizes websockets but it also has a lot of other functions built on top of it in order to do things such as HTTP handshakes, session ids, and it can even handle fail overs to other protocols when needed.
You got half of the issue so far. Adding the line socket.io/?EIO=3&transport=websocket you're specifying parameters for the socket.io server to take.
EIO=3 specifies the version number for engine.io in which socket.io is using. In this case you are saying engine.io version = 3
transport=websocket specifies which transport protocol to use. As i said earlier, socket.io uses other protocols in cases such as fail overs. This portion forces socket.io to use websocket as the preferred protocol.
Now the next half is the WebSocket. WebSocket allows for Extensions which includes different kinds of compression that are commonly used when sending data. Which I believe is what is causing your Parse Error
Try this (found here):
const WebSocket = require('ws');
const ws = new WebSocket('ws://server/socket.io/?EIO=3&transport=websocket', {
perMessageDeflate: false
});
By setting perMessageDeflate: false you are specifying "Do not compress data". Since as i said this is a WebSocket Extension there are different variations as well. Try these instead if it doesn't work
x-webkit-deflate-frame
perframe-deflate
As a disclaimer this information is from the research that I have done. Im not a "socket.io specialist" so if there's anything incorrect please comment and i'll edit the post.
Because Socket.IO doesn't guarantee that there will be a WebSockets server hosted like you're seeming to expect, you should instead use their standard client package.
npm i socket.io-client
Then use the package in your code:
const ioClient = require('socket.io-client')('https://example.com/1.0/scores')
The full docs for socket.io-client are available on their GitHub repo.
Note: Honestly, though, it's just better at this point to use WebSockets instead if possible. WebSockets has become well-supported in browsers and is quite standard. Socket.IO is rarely necessary and could add some overhead.

Is it possible to browserify the "tedious" module so that the nodejs program can be run in the browser?

I'm a beginner to Node.js and I'm currently building a Node.js program that accesses and queries a Microsoft Azure SQL database with the "tedious" module (see code below) and puts the data onto a html webpage. I want to run this code in a browser so I used browserify to bundle the modules together. However, when this code is run in Google Chrome, the following error is returned: require is not defined. Is there a fix? Is it even possible to use the tedious module in Chrome? If it isn't possible, do I need to use an intermediate server between the Node.js application and the webpage?
var Connection = require('tedious').Connection;
var config = {
userName: 'hackmatch',
password: 'hackvalley123!',
server: 'hackmatch.database.windows.net',
options: {encrypt: true, database: 'AdventureWorks'}
};
var connection = new Connection(config);
connection.on('connect', function(err) {
// If no error, then good to proceed.
console.log("Connected");
});
var Request = require('tedious').Request;
var TYPES = require('tedious').TYPES;
Thanks in advance for your help! :)
No. This module can only be used in Node.
tedious depends on the node.js net module to make a connection to the database server. This module has no equivalent on the browser, as web pages cannot make arbitrary network connections.
Even if it were possible to use this module in the browser, it'd be a terrible idea. You'd be allowing anyone on your web site to connect directly to your SQL server and run SQL queries. This can only end badly.

How to use the net module from Node.js with browserify?

I want to use the net module from Node.js on the client side (in the browser):
var net = require('net');
So I looked up how to get Node.js modules to the client, and browserify seems to be the answer. I tried it with jQuery and it worked like a charm.
But for some reason the net module does not want to work. If I write require('jquery') it works fine, but if I write require('net') it does not work, meaning my bundled .js file is empty.
I tried to search for something else, but the only thing I found is net-browserify on Github. With this, at least my bundle.js file is filled, but I get a JavaScript error using this (it has something to do with the connect function).
This is my code which works on the server side just fine:
var net = require('net-browserify');
//or var net = require('net');
var client = new net.Socket();
client.connect({port:25003}, function() {
console.log('Connected');
client.write('Hello, server! Love, Client.');
});
client.on('data', function(data) {
console.log('Received: ' + data);
client.destroy(); // kill client after server's response
});
client.on('close', function() {
console.log('Connection closed');
});
I assume that net-browserify lets you use a specific connect function, but I don't know which.
How can I use the net module from Node.js on the client side?
This is because net gives you access to raw TCP sockets - which browsers simply cannot do from the JavaScript end. It is impossible for net to ever be ported to the client side until such an API is written (allowing arbitrary tcp traffic).
Your best bet if you want to send tcp data from the client to the server is using web sockets using the socket.io module or the ws one.
Your best bet if you want clients to communicate directly is to look into WebRTC

Websocket server running fine but cannot connect from client (what url should I use?)

OK this is very simple to anyone who's used websocket and nodejs.
I have created a websocket server named ws_server.js and put it in C:\Program Files (x86)\nodejs where I have installed the nodejs framework. I started the server and it is running and it says it's listening on port 8080. So far so good, I have the server running.
Now I simply want to connect to it from client code so that I can do all that lovely stuff about capturing events using event listeners etc. The problem is, embarassingly, I cannot figure out what URL to use to connect to my websocket server.
function init() {
testWebSocket();
}
function testWebSocket() {
websocket = new WebSocket("ws://localhost:8080/"); // WHAT URL SHOULD BE USED HERE?
websocket.onopen = function(evt) { alert("OPEN") };
websocket.onclose = function(evt) { alert("CLOSE") };
websocket.onmessage = function(evt) { alert("MESSAGE") };
websocket.onerror = function(evt) { alert("ERROR") };
}
function doSend(message) {
// this would be called by user pressing a button somewhere
websocket.send(message);
alert("SENT");
}
window.addEventListener("load", init, false);
When I use ws://localhost:8080 the only events that trigger are CLOSE and ERROR. I cannot get the client to connect. I must be missing something very simple. Do I need to set up my nodejs folder in IIS for example and then use that as the URL?
Just to reiterate, the websocket server is running fine, I just don't know what URL to use to connect to it from the client.
EDIT: The websocket server reports the following error.
Specified protocol was not requested by the client.
I think I have got it working by doing the following.
var websocket = new WebSocket("ws://localhost:8080/","echo-protocol");
The problem being that I needed to specify a protocol. At least now I get the onopen event. ...if nothing much else
I was seeing the same error, the entire web server goes down. Adding the protocol fixes it but leaves me wondering why it was implemented this way. I mean, one bad request should not bring down your server.
You definitely have to encase it a try/catch, but the example code provided here https://www.npmjs.com/package/websocket (2019-08-07) does not. This issue can be easily avoided.
I just wanted to share a crazy issue that I had. I was able to connect to a websocket of an old version of a 3rd party app in one computer, but not to a newer version of the app in another.
Moreever, even in new computer with the new version of the app, The app was able to connect to the websocket, but no matter what I did, when I tried to connect with my own code, I kept getting the error message that the websocket connection failed
Long story short, They changed an apache configuration that allowed connecting to the websocket via a proxy.
In the old version, apache config was:
ProxyPass /socket/ ws://localhost:33015/ retry=10
ProxyPass /socket ws://localhost:33015/ retry=10
In the new version, apache config was changed to:
ProxyPass /socket/ ws://localhost:33015/ retry=10
By bad luck, I was trying to connect to ws://localhost/socket and not to ws://localhost/socket/. As a result, proxy was not found, and connection returned an error.
Moral of the story: Make sure that you are trying to connect to a websocket url that exists.
For me, the solution was to change the URL from ws:// to wss://. This is because the server I was connecting to had updated its security, and now only accepted wss.

Is there a browserless websocket client for Node.js that does not need to use a browser?

Socket.IO, etc all require the using of browser on the client side....just wondering, how can we have browserless websocket client for node.js ?
Current Recommendation
Use WebSocket-Node with my wrapper code (see below). As of this writing, no other public project that i know of supports the new hybi specification, so if you want to emulate current browser releases, you'll need WebSocket-Node. If you want to emulate older browsers, such as mobile Safari on iOS 4.2, you'll also need one of the other libraries listed below, but you'll have to manage "WebSocket" object name collisions yourself.
A list of public WebSocket client implementations for node.js follows.
Socket.IO
The socket.io client-test WebSocket implementation does hixie draft 75/76, but as of this writing, not hybi 7+.
https://github.com/LearnBoost/socket.io/blob/master/support/node-websocket-client/lib/websocket.js
i'm asking if they intend to update to hybi 7+:
http://groups.google.com/group/socket_io/browse_thread/thread/d27320502109d0be
Node-Websocket-Client
Peter Griess's "node-websocket-client" does hixie draft 75/76, but as of this writing, not hybi 7+.
https://github.com/pgriess/node-websocket-client/blob/master/lib/websocket.js
WebSocket-Node
Brian McKelvey's WebSocket-Node has a client implementation for hybi 7-17 (protocol version 7-13), but the implementation does not provide a browser-style WebSocket object.
https://github.com/Worlize/WebSocket-Node
Here is the wrapper code I use to emulate the browser-style WebSocket object:
/**
* Wrapper for Worlize WebSocketNode to emulate the browser WebSocket object.
*/
var WebSocketClient = require('./WorlizeWebSocketNode/lib/websocket').client;
exports.WebSocket = function (uri) {
var self = this;
this.connection = null;
this.socket = new WebSocketClient();
this.socket.on('connect', function (connection) {
self.connection = connection;
connection.on('error', function (error) {
self.onerror();
});
connection.on('close', function () {
self.onclose();
});
connection.on('message', function (message) {
if (message.type === 'utf8') {
self.onmessage({data:message.utf8Data});
}
});
self.onopen();
});
this.socket.connect(uri);
}
exports.WebSocket.prototype.send = function (data) {
this.connection.sendUTF(data);
}
SockJS
Just for reference, Marek Majkowski's SockJS does not include a node client. SockJS's client library is simply a browser dom wrapper.
https://github.com/sockjs/sockjs-client
Having just gone through this, I have to recommend:
https://github.com/Worlize/WebSocket-Node
Due to it's excellent documentation.
https://github.com/einaros/ws comes a close second.
Both are active and being kept up to date at this time.
Remy Sharp (#rem) wrote a Socket.io-client implementation that works on the server. I think this is what you're looking for: https://github.com/remy/Socket.io-node-client
A Node.js server is in no way bound to a web browser as a client. Any program can use whatever socket library is provided by its supporting libraries to make a call to a Node.js server.
EDIT
Responding to your comment: don't forget that Node.js is Javascript! If you want to execute code periodically -- in much the same way that a daemon process might -- you can use setInterval to run a callback every n milliseconds. You should be able to do it right there in your node program.
Right now (in Oct 2012) the recommended way to do it is using a the socket.io-client library, which is available at https://github.com/LearnBoost/socket.io-client

Resources