HTTP2 - How to have WebSocket-like functionality (Keep-Alive, EventSource, etc.) - node.js

Wondering how to setup a persistent connection between client and server in Node.js.
The persistent connection should be able to send requests back and forth from both sides. It seems like it needs to have a mechanism for delineating each request, such as \r\n if requests are JSON, but not sure what best-practices are here if it's already been done before. Wondering how web-sockets handle this.
Mozilla says Keep-Alive shouldn't be used in production, so wondering if that still holds with HTTP2.
With EventSource you can receive server events, but wondering if there is a way to add client events to send to the server.
In the end, I would like to have a simple setup for two-way communication like WebSockets, but am not sure of best practices in HTTP2 and if it should just be done with WebSockets. I would prefer to try to do this without websockets.
https://daniel.haxx.se/blog/2016/06/15/no-websockets-over-http2/

With all due respect, I believe you're under the mistaken assumption that the HTTP/2 connection is page specific.
In actuality, HTTP/2 connection are often browser wide connections. It's not possible for an HTTP/2 push to know which page/tab will use the data (possibly more than one).
Also, see the discussion here that includes a myriad number of reasons as to why HTTP/2 couldn't (or shouldn't) be used as a Websocket alternative.
On the other hand, if HTTP/2 is "promised" and Websockets are unavailable, than polling might be an option.
Polling with HTTP/2 will be significantly more resource friendly than polling with HTTP/1.1, even though it would still be far more expensive than Websocket push (or poll) due to the extra header and authentication data (it will also decrease security, but that's probably something nobody really cares about all that much).
P.S.
Websockets over HTTP/2
This is a non-issue unless HTTP/1.1 is retired (in fact, IMHO, this is intentional and good).
It's true that HTTP/2 connections can't be "upgraded" (changed) to Websocket connections, nor can they tunnel Websocket data, but that means absolutely nothing.
New Websocket connections use the existing HTTP/1.1 upgrade handshake and that's it.
Any HTTP/2 server that supports Websockets will support the handshake.
Keep-Alive
Mozilla warns against the non-standard Keep-Alive header. However, the Connection: keep-alive standard for HTTP/1.1 (which is also the default for HTTP/1.1 clients) is definitely recommended.
SSE (Server Sent Events)
SSE pre-date Websockets and they didn't get much traction in the community, while Websockets were adopted with a vengeance.
wondering if there is a way to add client events to send to the server
Simple - send an HTTP request. The reply can be asynchronously received with SSE.
I like Websockets better. As far as server-side goes, I find them easier to manage and code.

Related

What is difference between httpS and http/2?

I'm trying to understand what is the difference between HTTPS and http/2?
If I'm going to build a Node.js/express app, what should I use?
Can I use HTTPS with http/2?
Maybe if I use HTTPS, I don't need http/2 because it's the same, or HTTPS use http/2 under the hood?
I'm confused.
Someone is linked to me "difference between HTTP 1.1 and HTTP 2.0 [closed]", but I understand the difference between HTTP and HTTP2. I'm asking about HTTPS and HTTP/2
HTTP - A protocol used by clients (e.g. web browsers) to request resources from servers (e.g. web servers).
HTTPS - A way of encrypting HTTP. It basically wraps HTTP messages up in an encrypted format using SSL/TLS. The web is moving towards HTTPS more and more and web browsers are starting to put more and more warnings when a website is served over unencrypted HTTP. Unless you have a very good reason not to, use HTTPS on any websites you create now.
Digging into HTTP more we have:
HTTP/1.1 - this was the prevalent format of HTTP until recently. It is a text-based protocol and has some inefficiencies in it - especially when requesting lots of resources like a typical web page. HTTP/1.1 messages can be unencrypted (where web site addresses start http://) or encrypted with HTTPS (where web site address start with https://). The client uses the start of the URL to decide which protocol to use, usually defaulting to http:// if not provided.
HTTP/2 - a new version of HTTP released in 2015 which addresses some of the performance issues by moving away from a text based protocol to a binary protocol where each byte is clearly defined. This is easier to parse for clients and servers, leaves less room for errors and also allows multiplexing. HTTP/2, like HTTP/1.1, is available over unencrypted (http://) and encrypted (https://) channels but web browsers only support it over HTTPS, where it is decided whether to use HTTP/1.1 or HTTP/2 as part of the HTTPS negotiation at the start of the connection.
HTTP/2 is used by about a third of all websites at the time of writing (up to 50% of websites as of Jan 2020, and 67% of website requests). However not all clients support HTTP/2 so you should support HTTP/1.1 over HTTPS and HTTP/2 over HTTPS where possible (I believe node automatically does this for you when using the http module). I do not believe HTTP/1.1 will be retired any time soon. You should also consider supporting HTTP/1.1 over unencrypted HTTP and then redirect to HTTPS version (which will then use HTTP/1.1 or HTTP/2 as appropriate). A web server like Apache or Nginx in front of Node makes this easy.
HTTP/3 - the next version of HTTP, currently under development. It is expected to be finalised in 2020 though it will likely be late 2020 or even 2021 before you see this widely available in web servers and languages like node. It will be built on top of a UDP-based transport called QUIC (rather than the TCP-based protocol that HTTP/1.1 and HTTP/2 are based on top of). It will include part of HTTPS in the protocol so HTTP/3 will only be available over HTTPS.
In short you should use HTTP/1.1 over HTTPS, should consider HTTP/2 as well if easy to implement (not always possible as not quite ubiquitous yet - but getting there) and in future you might be using HTTP/3.
I suggest you get a firm understanding of all of these technologies (except maybe HTTP/3 just yet) if you want to do web development. It will stand you in good stead.

Is SSL secure connection available without browser call?

I have a question about SSL. As I know, when we use browser to request from https server, it will make an SSL handshake first then all data will be encryption in the connection. But if I make a request without browser (like request module in nodejs, postman...), will it be an SSL handshake and data encryption on the connection?
Anyone know please explain to me, thank you.
First, stop saying SSL. Its successor is TLS, and it will have 20 years next January.
TLS is a protocol sitting on top of TCP typically (other variants can also use UDP), and provides on top of TCP features some new features about endpoints authentication and transport confidentiality and integrity.
In a way, you can understand it as being sandwiched between TCP and the higher level application protocol, like HTTP.
Saying otherwise you can use many others protocols on top of TLS: you have all email related ones (SMTP, IMAP, POP, etc.), you can have FTP on top of it (while probably not a good idea nowadays), XMPP for realtime communications, etc.
In short, any protocol using TCP could use TLS with some adaptation.
So HTTP is one case among others. HTTP is between an HTTP client and an HTTP server, or webserver for short.
A browser is an HTTP client. One among many ones. When you use curl or wget you are also an HTTP client. So if any HTTP client access an http:// link it will first do the TLS handshake, after the TCP connection and before starting to do anything really related to the HTTP protocol.
You have specialized libraries dealing with TLS so that not all program need to recode everything about this again, since it is also complicated.

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.

Authentication in Golang WebSocket application

I am trying to implement user authentication in an application that primarily uses WebSockets, but I am unsure how to begin.
I am using the Gorilla mux and websocket packages.
I have thought about using the method described here (files main.go and auth.go), but does this approach secure against authenticated users somehow hijacking each others sockets like described in this article?
Can someone suggest a good method or package(s) in Go?
Authenticate as you would for a plain HTTP request before upgrading the connection to the WebSocket protocol. Use whatever methods or packages you would use for plain HTTP requests.
A WebSocket connection can be hijacked to the extent that a plain HTTP connection can be hijacked. The WebSocket protocol does not introduce any new issues here.
Socket.io is a layer above WebSockets, long-polling and other techniques for sending events from the server to a browser client. Issues with Socket.io do not necessarily apply to direct use of a WebSocket.

why engine io use polling first to establish the connection and then use websocket [duplicate]

This question already has answers here:
WebSockets protocol vs HTTP
(6 answers)
Closed 8 years ago.
when I read engine io protocol, I found it use polling to establish the connection and then upgrade the transport to websocket, I don't know why ? could you give me some idea?
It's because the WebSocket upgrade could fail, so having polling as a fallback mechanism is useful.
It doesn't really use polling. The initial HTTP url may look like it's a setup for polling, but that will go into play only if the server doesn't agree to upgrade the connection to the webSocket protocol.
A socket.io connection starts with a single TCP connection which is an HTTP request with certain webSocket headers set and then when the server responds that the webSocket protocol is supported, the connection is "upgraded" from HTTP to webSocket and both sides switch the protocol being used from HTTP to webSocket. This is how the webSocket protocol is specified.
If the client/server combination does not support webSocket, then and only then does socket.io resort to using long polling.
This particular design allows both webSocket and HTTP to share the same port and the socket.io design allows for a graceful fallback to long-polling if both sides don't agree on a webSocket upgrade.
engine.io/socket.io 1.x+ starts with polling first because that pretty much always works with all types of clients, allowing them to get connected very quickly. Then in the background, attempts to upgrade the connection are made (to WebSockets or whatever else). That way if the connection upgrades fail, nothing is lost because the polling is still working like before, so there is no down time.
The reason for this change from the old behavior of downgrading instead of upgrading is that WebSockets can be troublesome to get going correctly in some situations (e.g. problems with load balancers, proxies, etc.) and even if they do get connected there can be some extra delays involved. Also using the flash fallback for WebSockets would take some time to get connected because it involves extra roundtrips and some additional delays.

Resources