Currently working with Socket.IO using websockets. I have a couple of questions regarding how to interpret websockets in the chrome devtools:
When we have the following output in chrome:
Questions:
The method still is specified with the HTTP get method verb. Is this because this HTTP protocol is used to initiate the handshake?
If we have 4 type = websocket like in this example. Do we actually have 4 websocket connections?
One websockets was completed and the other 3 were still pending, what does this mean?
Yes, that's because the WebSocket handshake is an HTTP GET request. As you can see in the Status column, the server responded with "101 Switching Protocols", after which the protocol changed to the WebSocket protocol.
You seem to have one closed connection and three ongoing connections. Maybe whatever library you're using likes to create multiple connections?
The "pending" connections are active connections. The developer tools shows each connection that hasn't been closed yet as "pending". Not the most clear representation, but the dev tools were made to primarily deal with HTTP where individual requests don't last forever.
Free ProTip in case you didn't know: If you click on any of the requests and then click on the Frames tab, you can see all the WebSocket messages in real-time.
Related
I'm new user of envoy proxy, maybe someone can help me
I have 2 upstream hosts (UH1 and UH2), and configured envoy proxy to proxy (round robin) websocket connections from a client (frontend) to them.
Let's say UH1 has an active websocket connection (WC1) and UH1 becomes down (closes all its connections) I would like to keep the connection WC1 alive with a client and move the connection to UH2. Could anyone say if it is possible?
Thank you in advance!
I asked this question in the official google group of envoy-dev team and got an answer from Stephan:
This isn’t currently supported.
My sense is that one might be able to write an HTTP filter that takes
the place of the router filter to support this behavior in conjunction
with upgrade configs[1], but it’s probably a lot of work. That filter
would probably need to buffer the original HTTP request to be able
form a new websocket to a different upstream, and it would need to
decode websocket frames to avoid forwarding partial frames. Further if
the messages on the websocket are request/response oriented the filter
would have buffer websocket frames and have knowledge of their content
to avoid dropping requests.
In my experience, optimizing reconnect from the client and just
forming a new websocket connection is simpler to implement and also
provides benefits when the connection between the client and Envoy is
severed.
Stephan
https://groups.google.com/g/envoy-dev/c/3yCTqLx5ePE
This question already has answers here:
How to inspect WebSocket frames in Chrome properly?
(5 answers)
Closed 4 years ago.
I'm trying to inspect websocket traffic using Chrome Developer Tools. From my research it seems you should be able to see it using the network tab - and it even has a filter for 'ws'.
However I've been inspecting sites that I know are using websockets and can't find a way to inspect the messages being sent back and forth. Using Chrome v56, also tried Safari with no luck...
Does anyone know how this can be achieved?
You need to reload the page with the network tab open and filter by type 'ws'. This will show you a connection being made with a websocket. You can then click on the connection to show the traffic being sent back and forth with the server
https://developers.google.com/web/tools/chrome-devtools/network-performance/reference#frames
Information about this traffic is nested deeper in Network tab.
Using Chrome 58+, you will see
entry about connection to the websocket, on the main Network tab listing.
This change a protocol (HTTP status 101),
so
every possible next request being websocket traffic, will be visible under Frames tab of above entry.
Of course you can have more opened connections to different websockets, aggregated on the main "Network" tab by websocket type.
I'm trying to get a better understanding of how the server-side architecture works for WebSockets with the goal of implementing it in an embedded application. It seems that there are 3 different server-side software components in play here: 1) the web server to serve static HTTP pages and handle upgrade request, 2) a WebSockets library such as libwebsockets to handle the "nuts and bolts" of WebSockets communications, and 3) my custom application to actually figure out what to do with incoming data. How do all these fit together? Is it common to have a separate web server and WebSocket handling piece, aka a WebSocket server/daemon?
How does my application communicate with the web server and/or WebSockets library to send/receive data? For example, with CGI, the web server uses environmental variables to send info to the custom application, and stdout to receive responses. What is the equivalent communication system here? Or do you typically link in a WebSocket library into the customer application? But then how would communication with the web server to the WebSocket library + custom application work? Or all 3 combined into a single component?
Here's why I am asking. I'm using the boa web server on a uClinux/no MMU platform on a Blackfin processor with limited memory. There is no native WebSocket support in boa, only CGI. I'm trying to figure out how I can add WebSockets support to that. I would prefer to use a compiled solution as opposed to something interpreted such as JavaScript, Python or PHP. My current application using long polling over CGI, which does not provide adequate performance for planned enhancements.
First off, it's important to understand how a webSocket connection is established because that plays into an important relationship between webSocket connections and your web server.
Every webSocket connection starts with an HTTP request. The browser sends an HTTP request to the host/port that the webSocket connection is requested on. That request might look something like this:
GET /chat HTTP/1.1
Host: example.com:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
What distinguishes this request from any other HTTP request to that server is the Upgrade: websocket header in the request. This tells the HTTP server that this particular request is actually a request to initiate a webSocket connection. This header also allows the web server to tell the difference between a regular HTTP request and a request to open a webSocket connection. This allows something very important in the architecture and it was done this way entirely on purpose. This allows the exact same server and port to be used for both serving your web requests and for webSocket connections. All that is needed is a component on your web server that looks for this Upgrade header on all incoming HTTP connections and, if found, it takes over the connection and turns it into a webSocket connection.
Once the server recognizes this upgrade header, it responds with a legal HTTP response, but one that signals the client that the upgrade to the webSocket protocol has been accepted that looks like this:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
At that point, both client and server keep that socket from the original HTTP request open and both switch to the webSocket protocol.
Now, to your specific questions:
How does my application communicate with the web server and/or
WebSockets library to send/receive data?
Your application may use the built-in webSocket support in modern browsers and can initiate a webSocket connection like this:
var socket = new WebSocket("ws://www.example.com");
This will instruct the browser to initiate a webSocket connection to www.example.com use the same port that the current web page was connected with. Because of the built-in webSocket support in the browser, the above HTTP request and upgrade protocol is handled for you automatically from the client.
On the server-side of things, you need to make sure you are using a web server that has incoming webSocket support and that the support is enabled and configured. Because a webSocket connection is a continuous connection once established, it does not really follow the CGI model at all. There must be at least one long-running process handling live webSocket connections. In server models (like CGI), you would need some sort of webServer add-on that supports this long-running process for your webSocket connections. In a server environment like node.js which is already a long running process, the addition of webSockets is no change at all architecturally - but rather just an additional library to support the webSocket protocol.
I'd suggest you may find this article interesting as it discussions this transition from CGI-style single request handling to the continuous socket connections of webSocket:
Web Evolution: from CGI to Websockets (and how it will help you better monitor your cloud infrastructure)
If you really want to stick with the stdin/stdout model, there are libraries that model that for your for webSockets. Here's one such library. Their tagline is "It's like CGI, twenty years later, for WebSockets".
I'm trying to figure out how I can add WebSockets support to that. I
would prefer to use a compiled solution as opposed to something
interpreted such as JavaScript, Python or PHP.
Sorry, but I'm not familiar with that particular server environment. It will likely take some in-depth searching to find out what your options are. Since a webSocket connection is a continuous connection, then you will need a process that is running continuously that can be the server-side part of the webSocket connection. This can either be something built into your webServer or it can be an additional process that the webServer starts up and forwards incoming connections to.
FYI, I have a custom application at home here built on a Raspberry Pi that uses webSockets for real-time communication with browser web pages and it works just fine. I happen to be using node.js for the server environment and the socket.io library that runs on top of webSockets to give me a higher level interface on top of webSockets. My server code checks several hardware sensors on a regular interval and then whenever there is new/changed data to report, it sends messages down any open webSockets so the connected browsers get real-time updates on the sensor readings.
You would likely need some long-running application that incoming webSocket connections were passed from the web server to your long running process or you'd need to make the webSocket connections on a different port than your web server (so they could be fielded by a completely different server process) in which case you'd have a whole separate server to handle your webSocket requests and sockets (this server would also have to support CORS to enable browsers to connect to it since it would be a different port than your web pages).
According to the Wikipedia article: http://en.wikipedia.org/wiki/WebSocket,
The server sends back this response to the client during handshake:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
Does this close the connection (as HTTP responses usually do) or it is kept open throughout the entire handshake and it can start sending WebSocket frames straight away (assuming that it succeeds)?
An HTTP socket going through the handshake process to be upgraded to the webSocket protocol is not closed during that process. The same open socket goes through the whole process and then becomes the socket used for the webSocket protocol. As soon as the upgrade is complete, that very socket is ready for messages to be sent per the webSocket protocol.
It is this use of the exact same socket that enables a webSocket connection to run on the same port as an HTTP request (no extra port is needed) because it literally starts out as an HTTP request (with some extra headers attached) and then when those headers are recognized and both sides agree, the socket from that original HTTP request on the original web port (often port 80) is then switched to use the webSocket protocol. No additional connection on some new port is needed.
I actually find it a relatively elegant design because it makes for easy coexistence with a web server which was an important design parameter. And, a slight extra bit of connection overhead (protocol upgrade negotiation) is generally not an issue because webSocket connections by their very nature are designed to be long running sockets which you open once and use over an extended period of time so a little extra overhead to open them doesn't generally bother their use.
If, for any reason, the upgrade is not completed (both sides don't agree on the upgrade to webSocket), then the socket would remain an HTTP socket and would behave as HTTP sockets normally do (likely getting closed right away, but subject to normal HTTP interactions).
You can see this answer for more details on the back and forth during an upgrade to webSocket: SocketIO tries to connect using same port as the browser used to get web page
I have tried every conceivable haproxy configuration posted in blogs and stackoverflow, but I still cannot get haproxy and socket.io to work 100% of the time. In the majority of browsers that "support" web sockets it fails and falls back on long polling after missed heart beats. The browser appears to make the initial connection (nodejs debugging), but I cannot get the clients to receive the connection response. Is anyone else having similar problems? Below are the software version numbers and a couple of the configs I have tried.
haproxy 1.4.18
node 0.6.5
socket.io 0.8.7
Haproxy configurations (I have tried many more and numerous options):
http://engineering.bistri.com/post/14307969768/socket-io-haproxy-http-authentication
HAProxy + WebSocket Disconnection
http://pastebin.com/H3XNv0TQ
http://www.darkcoding.net/software/proxy-socket-io-and-nginx-on-the-same-port-over-ssl/ (minus ssl stuff)
Web sockets working in:
Safari 5 (Windows)
Chrome 11 (Linux)
Websockets cannot be reverse proxy'd because the 8 bytes of data the client must send after the headers is not advertised in a Content-Length header, so the intermediates won't forward that data until the handshake completes. And since the handshake needs those 8 bytes to complete, the handshake never completes and deadlocks, http://www.enotes.com/topic/WebSockets#Proxy_traversal. This is not the only source. Many more sources verify that they cannot be reverse proxy'd.