live http with node.js make server performance bad? - node.js

If use node.js create a http server.
Then use
res.write()
to response something to client.
That is use live http connection, server will not disconnect to client by itself.
Will it make server performance bad because too many connection?

It's not good to hold too many connections.
I think you should try sockit.io?

Related

Multiple Socket.io app processes cause each client socket connects and disconnects repeatedly

I am working on a nodejs app with Socket.io and I did a test in a single process using PM 2 and it was no errors. Then I move to our production environment(We use Google Cloud Compute Instance).
I run 3 app processes and a iOS client connects to the server.
By the way the iOS client doesn't keep the socket connection. It doesn't send disconnect to the server. But it's disconnected and reconnect to the server. It happens continuously.
I am not sure why the server disconnects the client.
If you have any hint or answer for this, I would appreciate you.
That's probably because requests end up on a different machine rather than the one they originated from.
Straight from Socket.io Docs: Using Multiple Nodes:
If you plan to distribute the load of connections among different processes or machines, you have to make sure that requests associated with a particular session id connect to the process that originated them.
What you need to do:
Enable session affinity, a.k.a sticky sessions.
If you want to work with rooms/namespaces you also need to use a centralised memory store to keep track of namespace information, such as the Redis/Redis Adapter.
But I'd advise you to read the documentation piece I posted, things might have changed a bit since the last time I've implemented something like this.
By default, the socket.io client "tests" out the connection to its server with a couple http requests. If you have multiple server requests and those initial http requests don't go to the exact same server each time, then the socket.io connect will never get established properly and will not switch over to webSocket and it will keep attempting to use http polling.
There are two ways to fix this.
You can configure your clients to just assume the webSocket protocol will work. This will initiate the connection with one and only one http connection which will then be immediately upgraded to the webSocket protocol (with socket.io running on top of that). In socket.io, this is a transport option specified with the initial connection.
You can configure your server infrastructure to be sticky so that a request from a given client always goes back to the exact same server. There are lots of ways to do this depending upon your server architecture and how the load balancing is done between your servers.
If your servers are keeping any client state local to the server (and not in a shared database that all servers access), then you will need even a dropped connection and reconnect to go back to the same server and you will need sticky connections as your only solution. You can read more about sticky sessions on the socket.io website here.
Thanks for your replies.
I finally figured out the issue. The issue was caused by TTL of backend service in Google Cloud Load Balancer. The default TTL was 30 seconds and it made each socket connection tried to disconnect and reconnect.
So I updated the value to 3600s and then I could keep the connection.

http server on top of net server

I implemented 2 webservers with express. One is the main, one is a microservice.
They are communicating through a HTTP REST API, and we had historically a socket.io server started on the microservice to watch the up/down status from the main server.
----HTTP-----
[main server] [microservice]
--socket.io--
I then realized that socket.io is not the right tool for that. So I decided to trade socket.io for a raw TCP socket.
So the question is : Is that possible to start the http server "ON TOP" of a raw TCP server (on the same port) ? (allowing to connect via TCP client AND to send HTTP requests ?)
I have this so far :
const app = express();
const server = http.createServer(app);
// const io = sio(server);
server.listen(config.port, config.ip, callback);
and I'm trying to integrate with this
What I'm trying to achieve, and achieved successuly with socket.io, is starting a socket server on the microservice, connect to it on the main server, keep it alive, and watch for events to keep a global variable boolean "connected" in sync with it. I'm using this variable to aknowledge the my frontend of microservice state, also to pre-check if I should try to request the microservice when requested, and also for loggin purposes. I'd like to avoid manual polling, firstly for maintenability, and also for realtime purpose.
Is that possible to start the http server "ON TOP" of a raw TCP server (on the same port) ?
Sort of, not really. HTTP runs on top of TCP. So, you could technically open a raw TCP server and then write your own code to parse incoming HTTP requests and send out legal HTTP responses. But, now you've just written your own HTTP server so it's no longer raw TCP.
The challenge with trying to have a single server that accepts both HTTP and some other protocol is that your server has to be able to figure out for any given incoming packets, what it is supposed to do with it. Is it an HTTP request? Or is it your other type of custom request. It would be technically feasible to write such a thing.
Or, you could use the webSocket technique that starts out as an HTTP request, but requests an upgrade to some other protocol using the upgrade header. It is fully defined in the http spec how to do this.
But, unless you have some network restriction that you can only have one server or one open port, I'd ask why? It's a complicated way to do things. It doesn't really cost anything to just use a different port and a different listening server for the different type of communication. And, when each server is listening only for one type of traffic, things are a heck of a lot simpler. You can use a standard HTTP server for your HTTP requests and you can use your own custom TCP server for your custom TCP requests.
I can't really tell from your question what the real problem is here that you're trying to solve. If you just want to test if your HTTP server is up/down, then use some external process that just queries one of your HTTP REST API calls every once in a while and then discerns whether the server is responding as expected. There are many existing bodies of code that can be configured to do this too (it's a common task to check on the well being of a web server).
The code you link to shows a sample server that just sends back any message that it receives (called an echo server). This is just a classic test server for a client to connect to as a test. The second code block is a sample piece of client code to connect to a server, send a short message and then disconnect.
From your comments:
The underlying TCP server wouldn't even be used for messaging, it just would be used to watch connect/disconnect events
The http server already inherits from a TCP server so it has all the same events for the server itself. You can see all those events in the http server doc. I don't know exactly what you want, but there are server lifetime events such as:
listening (server now listening)
close (server now closed)
And, there are server activity events such as:
connect (new client connected)
request (new client issues a request)
And, from the request event, you can get both the httpClientRequest and httpServerResponse objects which allow you to monitor the lifetime of an individual connection, including event get the actual socket object of an incoming connection.
Here's a code example for the connect event right in the http server doc.

Use NodeJS sockets to communicate with sockets in other languages

So basically I want to use NodeJS sockets to create a server as well as clients to speak between each other, my question is if a NodeJS socket can expect data from other languages, for example a socket in C++ send data to my program in NodeJS? I saw examples that always runs express for the server, I need to create the server in the same application. Thanks in advance and excuse my english.
my question is if a NodeJS socket can expect data from other languages
Yes. These are just normal network sockets on which you send/receive arbitrary data. Nothing about them are specific to Node.js
I saw examples that always runs express for the server
Express is a framework for handling HTTP requests. HTTP is a protocol that runs on top of a TCP socket. Express is irrelevant here, unless you want to use HTTP... in which case you'd use Express in conjunction with Node.js' built in HTTP library.
Don't confuse Web Sockets with normal sockets. They're really unrelated. Web Sockets are an abstraction on top of HTTP which emulate socket behavior between browsers and servers, but they really have nothing to do with each other, directly. You can't use a Web Socket client to connect to an arbitrary port on something.
sockets to create a server as well as clients to speak between each other
You, sir, need socket.io

When, if at all, is it more appropriate to use http over web sockets?

I am using Socket.IO with a MEAN stack and it's been excellent for low latency and bidirectional communication, but what would be the major draw back for using it for relatively static data as well as dynamic?
My assumption is that it would be more apt for sending more dynamic content. That being said, once a socket connection is established, how relevant is the amount of communication being done? Is there a time where it would be more appropriate to use http instead when a connection is constantly established throughout the user's direct interaction with the application?
Thanks!
WebSockets are a bidirectional data exchange within a HTTP connection. So the question is not if you use HTTP or WebSockets, because there is no WebSockets without HTTP. WebSockets are often confused with simple (BSD) sockets, but WebSockets are actually a socket-like layer inside a HTTP connection which is inside a TCP connection which uses "real" sockets. Or for anybody familiar with OSI layers: it as a layer 4 (transport) encapsulated inside layer 7 (application) and the main reason for doing it this strange way instead of using layer 4 directly is that plain sockets to ports outside of HTTP, SMTP and a few other protocols are no longer possible because of all the port blocking firewalls.
So the question should be more if you use simple HTTP or if you need to use WebSockets (inside HTTP).
With simple HTTP the client sends a request and the server sends the response back. The format is well defined and browser and server transparently support compression, caching and other optimizations. But this simple request-response pattern is limited, because there is no way to push data from server to client or to have a more (BSD) socket like behavior where both client and server can send any data at any time. There are various more or less good workarounds for this, like long polling.
WebSockets gives you a bidirectional communication, which makes it possible for the server to push data to the client or to send data in both directions at any time. And once the WebSocket connection is established by upgrading an existing HTTP connection the overhead for the data itself is very small, much smaller then with a full new HTTP request. While this sounds good you loose all the advantages of simple request-response HTTP like caching at the client or in proxies. And because client and server need resources to keep the underlying TCP connection open it needs more resources, which can be relevant for a busy server. Also, WebSockets might give you more trouble with middleboxes (like proxies or firewalls) then simple HTTP does.
In summary: if you don't need the advantages of WebSockets stay with simple request-response HTTP.

nodejs and webserver communication

This may seem like a stupid question but is it possible to establish a connection between a webserver and a nodejs application? I know that I can make requests from the nodejs server but is it possible to do something the other way around?
Assuming the webserver in question allows you to make outgoing network connections, you just use whatever features it has for doing so to connect to your node.js server and make a request, whether an HTTP request or some generic TCP request. For example, if the webserver were running PHP, you'd probably use the cURL PHP module to make an HTTP connection, or fsockopen() along with fread() and fwrite() for a raw TCP connection.
Note that some hosting arrangements may disallow outgoing connections.
You can use the request-library to do a HTTP request to another node.js server.

Resources