Using the Websocket Protocol - websocket

An opinion question: do you think it's safe already to use WebSockets what with the changing protocols? If not, when do you reckon the protocols will be finished?
Thanks!

The protocol isn't really changing much any more. Most of the discussion is around optional extensions and phrasing in the specification. There was no wire protocol change between HyBi-08, 09 and 10 (which is why the handshake version has stayed at '8') and very little change between 08 and the previous several versions. The protocol has also completed last call and been referred to the IESG/IETF so radical changes are not likely unless some serious issue is discovered that throws the protocol back into the HyBi work group for rework.
One of the bigger changes coming soon is for in the HTML API related to binary data support and close events. However, these changes are basically just additive and still backwards compatible with the current API.

Related

HTTP2 does not yet support etags?

I am currently making a server for dynamic and static files with Node. I'm trying to implement HTTP2. What surprises me is that it seems that the HTTP2 push does not support ETags!
When the client sends the headers to retrieve a file that starts with a push, and that it has accepted, it ignores the "IF-NONE-MATCH" header.
It's a waste, I do not understand the reason for this behavior. Is this the case or am I missing something?
As discussed in the comments the server pushes the resource, so there is no client request, so there is no Etag to send.
So HTTP/2 does support Etags - they just have no relevance for pushed requests.
And yes this does mean cached resources are ignored for Pushed resources - which is one of the big drawbacks of Push and why many people do not recommend using it. When a client sees the PUSH_PROMISE that a server sends before pushing a resource, it can reject it with a RST_STREAM request but by the time that makes it to the server often a good part (if not all) of the resource will have already been pushed.
There are a few ways around this:
You could track what has already been pushed using cookies for example. I've a simple example with Apache config here: https://www.tunetheweb.com/performance/http2/http2-push/. Of course that assumes that cookies and cache are in sync but they may not be (they can be cleared independently).
Some servers track what has already been pushed. Apache for example allows an HTTP/2 push diary to be configured (set to 256 items by default) which tracks items pushed on that connection. If you visit page1.html and it pushes styles.css, and then you visit page2.html and it also attempts to push styles.css Apache will not push it as it knows you already have it. However that only works if you are using the same connection. It you come back later on a new connection, but it's still in the cache then it will be re-pushed.
There was a proposal for Cache digests, which allow the browser to send an encoded list of what is in the cache at the start of any connection, and the server could use that to know whether to push an item or not. However work on that has been stopped recently as there were some privacy concerns about this.
Ultimately HTTP/2 Push has proven to be tricky to make useful and usage of it is incredibly low because of this. In large part due to this, but also because it is complex and there are other implication issues. Even if all those were solved, it's still easy to over push resources when perhaps it's best to let the browser request the resources in the order it knows it needs them. The Chrome team have even talked about turning it off and not supporting it.
Many are recommending using Early Hints with status code 103 instead, as it tells the browser what to request, rather than just pushing it. The browser can then use all it's usual knowledge (what's in the cache, what priority it should be requested with...etc.) rather than overriding all this like Push does.
Cheap plug, but if interested in this then Chapter 5 of my recently published book discusses this all in a lot more detail then can be squeezed into an answer on Stack Overflow.

How do I do multiplexing on OkHttp?

I see some older questions about using SPDY (though the code has changed significantly since then), but no insights into how to properly leverage multiplexing and/or pipelining in OkHttp. I've gone through all the examples and have yet to see anything specifically referring to this.
Is this something that is automatically done?
It’s automatic. If you have a server that supports HTTP/2, and a client that supports HTTP/2, it’ll do the right thing.

does it make sense to server-push woff2?

I'm reading quite a bit about http2's server-push. Also did some experimenting (on a beginner's level)...
Well, my question is: Does it make sense to server-push woff2 web-fonts? (since not every browser uses them), and, is there a method to push the correct font (if not already in the cache)?
Zach points out how important it is to have a fast font-delivery-solution, and CSS-Tricks (Chris Coyer) has a great method to get it done cache-aware...
Thank you!
david
Well that's an interesting question alright. The answer is: No you should not do this. But the reason is a little different than you might think...
For reasons that are a bit cryptic, fonts are always requested without credentials (basically cookies). For most browsers (Edge being the exception) this means the browser opens another connection for that request and this is important because HTTP/2 Pushes are linked to the connection. So if you push a resource on one connection, and the browser goes to get a resource from another connection it will not use that pushed resource (you do not push directly into the HTTP Cache as you might think).
This, and lots of other HTTP/2 Push trickiness and edge cases were discussed by Jake Archibald in his excellent HTTP/2 push is tougher than I thought article.
But it does beg the question of how you can decide what format to push even if this wasn't an issue, or if you wanted to send different image formats for example (that would be on the same connection). Other than looking at the User-Agent and guessing based off of that, there is now way for you to know what the browser supports.
There is a new HTTP Client Hints header currently being proposed which aims to allow the browser to indicate the device specifics. This currently is more concerned with image size and density, but could in theory also include the file formats that are supported.

Engine.io or SockJS, which one to choose?

I have run into trouble with Socket.io regarding memory leaks and scaling issues lately. My decision to use Socket.io was made over a year ago when it was undoubtedly the best library to use.
Now that Socket.io causes much trouble, I spent time looking for alternatives that became available in the meantime and think that both Engine.io and SockJS are generally well suited for me. However, in my opinion both have some disadvantages and I am not sure which one to choose.
Engine.io is basically the perfect lightweight version of Socket.io that does not contain all the features I do not require anyway. I have already written my own reconnection and heartbeat logic for Socket.io, because I was not satisfied with the default logics and I never intended to use rooms or other features that Socket.io offers.
But - in my opinion - the major disadvantage of Engine.io is the way connections are established. Clients start with slower jsonp-polling and are upgraded if they support better transports. The fact that the clients which support websockets natively (number increasing steadily) have a disadvantage in the form of a longer and unstable connection procedure over those clients which use outdated browsers, contradicts my sense of how it should be handled.
SockJS on the other hand handles the connections exactly as I would like to. From what I have read it seems to be pretty stable while Engine.io has some issues at this time.
My app is running behind an Nginx router on a single domain, therefore I do not need the cross-domain functionality SockJS offers. Because of providing this functionality, however, SockJS does not expose the cookie data of the client at all. So far I had a 2-factor authorization with Socket.io via cookie AND query string token and this would not be possible with SockJS (with Engine.io it would).
I have read pretty much all what is avilable about and pros and cons of both, but it seems there is not much being discussed or published so far, espacially about Engine.io (there are only 8 questions tagged with engine.io here).
Which of the 2 libraries do you prefer and for which reason? Do you use them in production?
Which one will likely be maintained more actively and could have a major advantage over the other in the future?
Have you looked at Primus? It offers the cookie requirements you mention, it supports all of the major 'real-time'/websocket libraries available and is a pretty active project. To me it also sounds like vendor lock-in could be a concern for you and Primus would address that.
The fact that it uses a plugin system should also a) make it easier for you to extend if needed and b) may actually have a community plugin that already does what you need.
Which of the 2 libraries do you prefer and for which reason? Do you use them in production?
I have only used SockJS via the Vert.x API and it was for an internal project that I would consider 'production', but not a production facing consumer app. That said, it performed very well.
Which one will likely be maintained more actively and could have a major advantage over the other in the future?
Just looking over the commit history of Engine.io and SockJS, and the fact that Auttomatic is supporting Engine.io makes me inclined to think that it will be more stable, for a longer period of time, but of course that's debatable. Looking at the issues for Engine.io and SockJS is another good place to evaluate, but since they're both split over multiple repos it should be taken with a grain of salt. I'm not sure where/how Automattic is using Engine/Socket.io, but if it's in WordPress.com or one of their plugins, it has substantial production-at-scale battle testing.
edit: change answer to reflect cookie support confirmed by Primus author in comments below
I'd like to redirect you to this (quite detailed) discussion thread about SockJS and Engine.io
https://groups.google.com/forum/#!topic/sockjs/WSIdcY14ciI
Basically,
SockJS detects working transports before marking the connection
as open. Engine.io will immediately open the connection and upgrade
it later.
flash, one of the Engine.io fallbacks
(and not present in SockJS) loads slowly and in environments
behind proxies takes 3 seconds to timeout.
SockJS doesn't use flash and therefore doesn't need to work around
this issue.
SockJS does the upgrade on start. After that you have
a consistent experience. You send what you send, you receive
what you receive.
Also, as far as I can tell, engine.io-client (the client-side) library for engine.io, does not support requirejs builds, so that's another negative point. (SockJS does build perfectly).
You may also consider node-walve. Complete WebSocket basic. Extremely performant as fully stream based.
Example of how to use:
walve.createServer(function(wsocket) {
wsocket.on('incoming', function(incoming) {
incoming.pipe(process.stdout, { end: false });
});
}).listen(server);
It may not be the best choice if you feel not secure in the nodejs environment (e.g. extending prototypes for API sugar), contributing to the project (though the code is more readable as socket.io).

Which FTP transfer modes are widely used?

Reading the FTP RFC (RFC959), I notice some modes that I've never seen used, and indeed don't seem to be implemented by popular FTP software (vsftpd for example). In particular, for the STRU command, only file mode "STRU F" is commonly used, and for the MODE command, only stream mode "MODE S" is commonly used.
So the question is, when following best practice for developing interoperable FTP client and server software:
Is it useful to support the other STRU options (record and page)? These seem like something very old fashioned.
Is it useful to support the other MODE options (block and compressed)? I can see the point in compressed, but I'm particularly wondering whether any clients/servers will expect block to be there.
Are there any surveys of which existing FTP implementations support which options?
(On the MODE one, I can see why compressed is useful, I'm more wondering about whether any clients/servers will expect block mode to be there).
I maintain a custom FTP server and regularly refer to http://cr.yp.to/ftp.html for these sort of questions. Specificly, I followed the suggestions for TYPE/MODE/STRU at http://cr.yp.to/ftp/type.html and so far have had no issues.
No client I've seen connect has sent an STRU request besides "STRU F". Similarly, I've only ever seen "MODE S".
I would suggest to search for open source FTP clients and servers (especially those still being actively updated) and look at how many of them implement these "obsolete" transfer modes.
I made once (about seven years ago) a FTP client and implemented just the most basic transfer modes (ASCII and binary, if I remember correctly). Never had a problem with any server when using it.
It sounds like you are mostly concerned with interoperability. The answer is a bit different between client and server.
For server, you want to implement the basic modes that clients use. For every client, you need to support a minimum of one configuration, so the number of combinations should be relatively low. Beyond the minimum, supporting active -and- passive mode would probably the major addition (the mozilla community has wanted passive support for a long time, and it is probably never going to happen).
If you are a client, providing good URL support and date/time handling is probably the biggest barrier.

Resources