The official doc on agent.maxSockets says that it indicates the limit on how many concurrent sockets my http(s) server can have. So I did some tests with http.globalAgent.maxSockets set to 5 and I expected that I can have only 5 open websockets. But turns out I can have more than 50 open websockets. Can anybody explain what does agent.maxSockets really mean?
http.Agent instances are used with outbound http clients (e.g. via http.request()), not inbound clients into an http.Server. So if you were to use an http.Agent with maxSockets set to 5 with http.request(), then there would only be at most 5 connected sockets to a particular server at any given time.
Related
Is it possible to implement a WebService over a WebRTC Data Channel ?
The idea is:
The client makes one https request to the server for signaling and session establishment
The client and the server start to communicate via a WebRTC DataChannel bidirectionally
Benefits?:
Performance ?
Requests goes over one connection and the standard allows for multiple datachannels over the same connection ( ports )
Flexible networking topologies
UDP
End to end encryption
The server can send events over the same connection
Load balancing could be implemented from a pool of servers client side without a load balancer , or all kinds of different solutions
Currently being debated the addition of DataChannels to Workers/Service Workers/ etc https://github.com/w3c/webrtc-extensions/issues/64
Drawbacks:
Application specific code for implementing request fragmentation and control over buffer limits
[EDIT 3] I don't know how much of a difference in terms of performance and cpu/memory usage will it be against HTTP/2 Stream
Ideas:
Clients could be read replicas of the data for sync, or any other applications that are suitable for orbit-db https://github.com/orbitdb/orbit-db in the public IPFS network, the benefit of using orbit-db is that only allows to the owner to make writes, then the server could additionally sign with his key all the data so that the clients could verify and trust it's from the server, that could offload the main server for reads, just an idea.
[EDIT]
I've found this repo: https://github.com/jsmouret/grpc-over-webrtc
amazing!
[EDIT2]
Changed Orbit-db idea and removed cluster IPFS after investigating a bit
[EDIT3]
After searching Fetch PROS for HTTP/2 i've found Fetch upload streaming with ReadableStreams, i don't know how much of a difference will it be to run GRPC (bidi) over a WebRTC DataChannel or a HTTP/2 Stream
https://www.chromestatus.com/feature/5274139738767360#:~:text=Fetch%20upload%20streaming%20lets%20web,things%20involved%20with%20network%20requests).
Very cool video explaining the feature: https://www.youtube.com/watch?v=G9PpImUEeUA
Lots of different points here, will try to address them all.
The idea is 100% feasible. Check out Pion WebRTC's data-channels example. All it takes a single request/response to establish a connection.
Performance
Data channels are a much better fit if you are doing latency sensitive work.
With data channels you can measure backpressure. You can tell how much data has been delivered, and how much has has been queued. If the queue is getting full you know you are sending too much data. Other APIs in the browser don't give you this. There are some future APIs (WebTransport) but they aren't available yet.
Data channels allow unordered/unreliable delivery. With TCP everything you send will be delivered and in order, this issue is known as head-of-line blocking. That means if you lose a packet all subsequent packets must be delayed. An example would be if you sent 0 1 2 3, if packet 1 hasn't arrived yet 2 and 3 can't be processed yet. Data channels can be configured to give you packets as soon as they arrive.
I can't give you specific numbers on the CPU/Memory costs of running DTLS+SCTP vs TLS+WebSocket server. It depends on hardware/network you have, what the workload is etc...
Multiplexing
You can serve multiple DataChannel streams over a single WebRTC Connection (PeerConnection). You can also serve multiple PeerConnections over a single port.
Network Transport
WebRTC can be run over UDP or TCP
Load Balancing
This is harder (but not intractable) moving DTLS and SCTP sessions between servers isn't easy with existing libraries. With pion/dtls it has the support to export/resume a session. I don't know support in other libraries however.
TLS/Websocket is much easier to load balance.
End to end encryption
WebRTC has mandatory encryption. This is nice over HTTP 1.1 which might accidentally fall back to non-TLS if configured incorrectly.
If you want to route a message through the server (and not have the server see it) I don't think what protocol you use matters.
Topologies
WebRTC can be run in many different topologies. You can do P2P or Client/Server, and lots of things in between. Depending on what you are building you could build a hybrid mesh. You could create a graph of connections, and deploy servers as needed. This flexibility lets you do some interesting things.
Hopefully addressed all your points! Happy to discuss further in the comments/will keep editing the question.
I was also wondering about this HTTP-over-WebRTC DataChannel idea a couple of years ago. The problem at hand was how to securely connect from a web app to an IoT device (raspberry pi) that sits behind a firewall.
Since there was no readily available solution, I ended up building a prototype. It did the job and has been in live deployment since 2019.
See this technical blog post that covers the design and implementation in more detail:
https://webrtchacks.com/private-home-surveillance-with-the-webrtc-datachannel/
High level architecture:
Simplified sequence diagram:
Recently began the process of extracting the code into a standalone repo.
https://github.com/ambianic/peerfetch
If your main use-case exchanges small content, you may have a look at CoAP RFC 7252. A peer may easily implement both roles, client and server, though the exchanged messages for request and response share the same fomat.
For some advanced usage of DTLS 1.2, DTLS Connection ID can do some magic for you.
If you don't stick to javascript and java is an option, you may check the open source project Eclipse/Californium. That's a CoAP/DTLS implementation, which comes with DTLS Connection ID and some prepared advanced examples as built-in-cid-load-balancer-support or DTLS-graceful-restart.
Note: I've already read this question, its main answer and all the linked questions given there (more than 8 questions, such as this one but it talks about Flash, etc.). They are all ~ 2011, and things might have changed, thanks to new tech like WebRTC, etc.
Question:
If I give my IP to a friend, and he gives me his IP, can we send bytes to each other directly in the browser, with Javascript? (both users not in the same local network but connected via internet)
If possible, without any 3rd party server. In this case we would both load a local HTML file containg the Javascript code allowing connection to each other. It seems possible to do such things with "chownat":
allows clients behind NATs to communicate with a server behind a separate NAT with no port forwarding no DMZ setup, and no 3rd party involvement.
If not possible without any server, then is it possible with a server involved just at the beginning of the process? (to make peers meet / know each other / to initiate the connection). Then once connection is established, the server would not be needed anymore: the 2 peers send bytes to each other, without server.
Is 1. or 2. possible nowadays with a standard browser (Firefox, Chrome, etc.) and without any router port configuration? With WebRTC for example?
Note: I've read about RTCDataChannel and tried this Simple_RTCDataChannel_sample but I don't see how two distant people can use this to connect to each other, this sample doesn't cover that. Here is the live demo. I don't see how it can be turned into a connection between two peers on internet.
If I give my IP to a friend, and he gives me his IP, can we send bytes to each other directly in the browser, with Javascript? [...] If possible, without any 3rd party server.
No, WebRTC uses session establishment tokens which cannot be reused, they must be generated anew for each connection. The IP address is not sufficient to establish a connection, at least such a token must also be generated and exchanged, either manually or...
If not possible without any server, then is it possible with a server involved just at the beginning of the process?
Yes, the server would act as rendezvous point to exchange tokens and optionally as STUN server.
Is 1. or 2. possible nowadays with a standard browser (Firefox, Chrome, etc.) and without any router port configuration?
That depends on your router(s), more specifically behind what types and how many layers of NAT each party is. But if they are well-behaved then the browsers will attempt NAT traversal with the help of a STUN server to establish a direct connection.
But generally browsers are less powerful when it comes to NAT traversal than native applications since native applications can talk to the firewall, UPnP/PMP/PCP routers and may also try NAT traversal techniques (e.g. TTL-based punching, linear port guessing) that are not part of the standard ICE/STUN approach.
I'm developing an application that uses SockJS to update some common data across the other applications connected to the server. The problem comes when
I try to open it in two browser tabs because just one of them achieve the connection while the other keeps waiting until the timeout comes.
¿Can anyone explain me why is this happening? ¿Is there any solution?
On the server I'm using an Spring implementation of SockJS whit the WebSocket transport disabled because the application server doesn´t support it.
To anyone who find this helpful, I ended up discovering that the HTTP/1.1 protocol recommends a connection limit of two connections per domain, so, the browsers share this two connections across any tab/window/iframe. As a result, when this two connections are consummed, every other connection/request have to wait until one of that two connections is released.
Libraries like cometd handle this by detecting when multiple clients are connected and falling back to normal poll.
I'm quite a bit new to node.js. I have question, can we connect two node.js servers? these 2 servers handle clients and perform there individual action I want to establish a connection between these two servers so that these 2 servers can share there status to each other.
Can anyone please help me?
it is somewhat like this
server1 ==> room1[client1, client2,client3]
server2 ==> room2[client4,client5, client6]
here I want to make a communication between these two servers.
Sure: just use a socket as you would with any other programming language that's capable of network communications.
One of the servers will need to listen on a TCP port (using net.createServer) and the other one connects to it using net.connect.
This is easy if you really only have two servers. If you have more, you will need either a main "arbiter", i.e. a (listening) relay server that receives messages from other servers and transfer them to real recipients, or a mesh network (not a good starting point if you're a networking newbie).
JsonSocket seems to be an interesting project for transfering JSON messages using raw TCP sockets, although I didn't test it myself.
I have a machine running node.js (v0.1.32) with a tcp server (tcp.createServer) and a http server (http.createServer). The http server is hit by long polling requests (lasting 50 sec each) from a comet based application on port 80. And there are tcp socket connections on port 8080 from an iphone application for the same purpose.
It was found that the server was not able to handle more connections (especially the tcp connections while the http connections appeared fine!!??) for a while and was normal only after a restart.
For load testing the connections I have created a tcp server and spawned 2000 requests and figured that the connections starting to fail after the max file descriptor limit on machine is reached (default 1024). Which is a really very small number.
So, a novice question here: How do I scale my application to handle more number of connections on node.js and how I handle this issue.
Is there a way to find out how many active connections are there at the moment?
Thanks
Sharief
Hey Joey! I was looking for a unix solution that would help me figure out how many open connections at a given moment anytime on my machine. The reason was my server was not able to handle requests after a certain number of connections. And figured that my machine can handle only 1024 open connections at a time i.e., the ulimit file descriptor value which defaults to 1024. I have modified this value by setting ulimit -n that suits my requirement.
So to check the open connections I used lsof that gives me the list of open files and figured how many connections are open via each port I was using.
You can get the count of connections by using below:
var server = http.createServer(app);
server.getConnections(function(error, count) {
console.log(count);
});
Using this you keep check on connection and when it cross a threshold then close the previous connections. Hope it helps.
I don't know if there's a built-in way to get the number of active connections with Node, but it's pretty easy to rig something up.
For my comet-style Node app I keep an object that I add connections to as a property. Every X seconds I iterate over that object and see if there are any connections that should be closed (in your case, anything past your 50 second limit).
When you close a connection, just delete that property from your connections object. Then you can see how many connections are open at any time with Object.size(connections)