When I send msg to a WebSocket client is it blocking or non blocking code ?
ws.send(msg);
In other words, is it a good practice to wrap a send within a setTimeout ?
I am using the Node Einaros WS library but I think this question applies to many other libraries such as Socket.Io or Engine.Io too.
Firstly, to wrap a blocking function within a setTimeout is only going to delay the blocking call, right? So it wouldn't matter if you did that or not. The non-blocking nature of node comes from the fact that the underlying engine runs an event system to let you know when traditional blocking calls (such as file system retrieval) are complete.
Websockets are a "fire and forget" protocol, which I think is what you're trying to ask. The server and client do not wait for a response and instead use the same system as I mentioned above. They will 'listen' to events when they are emitted from the other side and then deal with a process. It is worth noting that websocket communication in the browser do so only under the TCP protocol, meaning if a packet is lost then it will request it again from the server. This is not usually a problem, but in a realtime game sense where milliseconds are important, this is not usually ideal.
Related
I have a node.js process which has several entry points, including a tcp server, websocket server, and named pipe server. I am wondering if any interactions with these connections will be blocking.
Example: for a given connection, if there isnt anything in the buffer because the client didnt send anything yet, will this block all other code from running in the Node.js process until the client sends data?
My understanding is that node will offload I/O operations like these to the system kernel, so it wouldnt hold up the call stack.
Most likely I am getting something wrong here so please let me know! Thank you.
This is a very interesting question!
I would recommend you to start by understanding what the event loop is (reading https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/) and then understanding the difference between blocking & non-blocking calls (reading https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/).
Now we'll know a bit more about how node works behind the scenes, what blocking and non-blocking operations are and therefore we're equipped to understand and spot what will or won't block our loop.
Will a TCP connection block it? There may be a module out there that will, it really depends on each case, library, implementation.
Regarding TCP on the "native" implementation, if you're using the node.js Net module you'll find that it is a:
module [that] provides an asynchronous network API for creating stream-based TCP or IPC servers
Therefore, in principle, it will be non-blocking.
As an example, if we look at the socket.write documentation itself, we'll find that this function:
Returns true if the entire data was flushed successfully to the kernel buffer. Returns false if all or part of the data was queued in user memory. 'drain' will be emitted when the buffer is again free.
Therefore it should not block.
PS: Another interesting article on this subject is https://medium.com/#hnasr/when-nodejs-i-o-blocks-327f8a36fbd4
Happy reading, and keep an eye out for blocking function calls!
One thing I know for a fact is that Node.js shouldn't be used to intensive CPU tasks. Now, imagine that I have a node.js server receiving audio stream from several clients (from MIC). This audio is buffered in a c/c++ addon by doing memcpy (which is very fast). But when the endevent is triggered, this addon will convert "audio-to-command" and send it, to client. This conversion consumes 75ms (max). Can Node.js be considered an reliable solution for this problem? 75ms can be considered an intensive task in node.js? What is the maximum time recommended to blocking operations?
Blocking is not a Node.js way.
You can make this operation asynchronously (in a separate thread), without any blocking, and invoke a callback from your addon when the operation will be finished, so the main node.js thread will not be blocked and will be able to handle other requests.
There are good helpers like AsyncWorker and AsyncQueueWorker in NAN.
https://github.com/nodejs/nan
Also there are C++ libraries to work with WebSockets, so I would think about a direct connection between clients and the addon.
I'm trying to set up a server that can handle a high sustained amount of simultaneous requests. I found that at a certain point, the server won't be able to recycle "old" TCP connections quickly enough to accommodate extreme amounts of requests.
Do websockets eliminate or decrease the amount of tcp connections that a server needs to handle, and are they a good alternative to "normal" requests?
Websockets are persistent connections so it really depends on what you're talking about. The way socket.io uses XHR is different from a typical ajax call in that it hangs onto the request for as long as possible before sending a response. It's a technique called long-polling and It's trying to simulate a persistent connection by never letting go of the request. When the request is about to timeout it sends a response and a new request is initiated immediately which it hangs onto yet again, and the cycle continues.
So I guess if you're getting flooded with connections because of ajax calls then that's probably because your client code is polling the server at some sort of interval. This means that even idle clients will be hitting your server with fury because of this polling. If that's the case then yes, socket.io will reduce your number of connections because it tries to hang onto one single connection per client for as long as possible.
These days I recommend socket.io over doing plain ajax requests. Socket.io is designed to be performant with whatever transport it settles on. The way it gracefully degrades based on what connection is possible is great and means your server will be overloaded as little as possible while still reaching as wide an audience as it can.
I am new to C++ and I am trying to develop a client-server application based on the boost::asio library. I am (still) not able to understand properly the difference between sync and async modes. I've previously studied web protocol services such as HTTP and AJAX. From this explanation, it's clear that HTTP is synchronous and AJAX is asynchronous. What is the difference in TCP socket communication in terms of sync and async? And which mode is better from the perspective of enterprise-level multi-threaded application development, and why?
As I understand synchronous mode, the client blocks for a while until it receives the packet/ data message from the server. And in async mode, the client carries out another operation without blocking the current operation. Why is this different? Is async synonymous with UDP? It seems it doesn't care if it receives transmission acknowledgement.
TCP transmission is always asynchronous. What's synchronous or asynchronous is the behaviour of the API. A synchronous API does things while you call it: for example, send() moves data to the TCP send buffer and returns when it is done. An asynchronous API starts when you call it, executes independently after it returns to you, and calls you back or provides an interrogable handle via which completion is notified.
HTTP is synchronous in the sense that you send a request, receive a response, display or process the response, all in that order.
Ajax is asynchronous only in the sense that it operates independently of the page request/response cycle in the surrounding HTTP request. It's a poor choice of terminology. It would have been better to use a term like 'nested', 'out of band', ...
I have read that a HTTP server created in node.js does not create new threads for each incoming connection(request). Instead it executes a function that has been registered as a callback corresponding to the event of receiving a request.
It is said that each connection is represented by some small space in the heap. I cannot figure this out. Are connections not represented by sockets ? Should sockets not be opened for every connection made to the node.js server and this would mean each connection cannot be represented by just a space allocation in the javascript heap ?
It is described on the nodejs.org website that instead of spawning threads (2mb overhead per thread!) per connection, the server uses select(), epoll, kqueue or /dev/poll to wait until a socket is ready to read / write. It is this method that allows node to avoid thread spawning per connection, and the overhead is that associated with the heap allocation of the socket descriptor for the connection. This implementation detail is largely hidden from developers, and the net.socket API exposed by the runtime provides everything you need to take advantage of that feature without even thinking about it.
Node also exposes its own event API through events.EventEmitter. Many node objects implement events to provide asynchronous (non-blocking) event notification, which is perfect for I/O operations, which in other languages - such as PHP - are synchronous (blocking) by default. In the case of the node net.socket API, events are triggered for several API methods dealing with socket I/O, and the callbacks that are passed by parameter to these methods are triggered when an event occurs. Events can have callback functions bound to them in a variety of different ways, accepting a callback function as a parameter is only a convenience for the developer.
Finally, do not confuse OS events with nodejs events. In the case of the net API, OS events are passed to the nodejs runtime, but nodejs events are javascript.
I hope this helps.