Error during WebSocket handshake: 'Connection' header is missing - node.js

I'm completely new to Node, and even newer to Socket.io. I just got my first chat application online at spaiglas.com, which works despite an error in the developer console that is fairly straightforward...
WebSocket connection to 'ws://example.com/...' failed
: Error during WebSocket handshake
: 'Connection' header is missing
Here is a codepen with all of my code. I've uploaded it to my hosting provider, which is using Passenger via cPanel on an Apache server in a Node 9.11.2 environment.
From what I've been reading, the 'Connection' headers can't be set using AJAX, which is supposedly a security risk, but instead is handled by the server? Is it possible to manually set this header?
I have noticed by looking at the headers that early on usually one of them always successfully switches/upgrades the protocol to WebSockets, but then the platform always seems to revert back to HTTPS/polling. In the case below, which I observed just now, there were actually 2 out of now 67 instances whereby it successfully switched to and used the WebSockets protocol.

You need to initialize socket.io before you start your HTTP server that is listening on port 80. In the docs it is...
var http = require('http').Server(app);
var io = require('socket.io')(http);
And then later, you call http.listen(3000, ...). This will start the socket.
On the client, your path is also incorrect. Websockets is a protocol (ws://somedomain.com), just like HTTP. When you connect via http:// that is a different protocol. I would either not pass it anything, or use namespaces which you can find in the socket.io documentation.
Socket.io reverts to long polling and sometimes doesn't even use websockets (which is partly why it is generally slower than libraries like ws on npm). Because of that, passing http:// into the io(...) on the client may not be wrong with their library, but I would remove it anyway and do my above suggestion.

Related

How to deal with websockets on IIS on port 80 in general and when using ISAPI

We are using IIS and ISAPI DLL's to deliver our web application. We can see the websocket upgrade request coming from the browser in our ISAPI application. We could accept the request and pass the connection to a thread to continue the conversation. The thread would now be the "websocket server" so in this sense we are able to handle incoming http (and https on 443) then switch from http to websocket, is that right?
I am assuming Microsoft's implementation of websockets only works with asp.net?
Some people have said to me "put the websocket server on a different port and have the javascript connect to that port." But, then the websocket server is not using HTTPS (SSL).
For example:
var socket = new WebSocket('ws://echo.websocket.org');
I have lots of books and examples but this simple issue is eluding me.
The thread would now be the "websocket server" so in this sense we are able to handle incoming http (and https on 443) then switch from http to websocket, is that right?
Yes, if the client side send the request which contains the Upgrade: websocket, the websocket serve will switch from http to websocket.
I am assuming Microsoft's implementation of websockets only works with asp.net?
If you means the websocket .net library, it will just work with .net application like asp.net, it is developed based on the .net framework.
For example: var socket = new WebSocket('ws://echo.websocket.org');
As far as I know, the websocket also contains the secure connection like https.
Like below image shows:
More details about the difference between http and websocket, you could refer to below article:
https://developerinsider.co/difference-between-http-and-http-2-0-websocket/

Expressjs app, using websockets for chat. Use different port for websocket server?

I'm making an app using node.js' express framework which serves both html content over http and uses websockets for a chat feature. I'm wondering how I can accomplish both at the same time. My idea is to use a different port for websocket connections (so http requests would come to port 3000 and websockets would connect on port 3001) but I don't know if that's a good solution. I'm especially worried about deployment to something like heroku and if I can specify different ports for my app.
I'm wondering how I can accomplish both at the same time.
The webSocket protocol is specially designed so it can run on the same port as your regular web server requests. So, you don't need a separate port in order to have both a web server and chat running using webSockets.
This works because a webSocket connection is always initiated with an http request that sets a few special headers. The receiving web server can then detect those special headers and know that this incoming http request is actually a request to initiate a webSocket connection. With a particular response, the client and server then agree to "upgrade" the connection and switch to the webSocket protocol. From that point on, that particular TCP connection uses the webSocket protocol.
Meanwhile any incoming http request that does not have the special webSocket headers on it is treated by your web server as just a regular http request. In this way, the same server and the same port can be used for both webSocket connections and regular http requests. No second port is needed.
Another advantage of this scheme is that the client can avoid the cross-origin issues that it would run into if it was trying to use a different port than the web page it was loaded from.
I'm especially worried about deployment to something like heroku and
if I can specify different ports for my app.
If you were to actually use two ports, then you would need to create two separate servers, one listening on each port since a given server can only listen on one port. In node.js, the two servers could both be in the same node.js app (making it easier to share data between them) or you could put them in completely separate node.js processes (your choice).
And, if you used multiple ports, you'd also have to support CORS so that the browser would be allowed to connect to the separate port (to avoid same-origin restrictions).

SocketIO on port 80 together with Express

I have ExspressJS app run with Socket.io, due to firewall issues with higher port for SIO i want to switch that both will work on port 80.
Found this small article and on my dev machine it's look working good.
My question is, is it really goo to do that? is it a good practice? if not why?
Please advise.
It makes absolute sense to run socket.io and your web server on the same port.
The webSocket protocol (which socket.io is based on) is specifically designed for this to be the primary way that socket.io is used for a bunch of reasons including same-origin permissions and client and server firewall routing of port 80.
In case you didn't realize it, every socket.io connection starts with an HTTP request to a specific route and then once the initial handshake between client and server has been confirmed, then the protocol is "upgraded" from HTTP to webSocket. Because all socket.io connections connect in on a very specific route, all other HTTP connections can easily be separated out and be treated by your web server as regular web requests.

socket.io websocket connection invalid (latest chrome)

After installing node.js, I followed this tutorial to start a simple chat server. It was very easy to setup and is working, but I have noticed two problems:
1.) I am getting this warning from socket.io
info - socket.io started
debug - served static /socket.io.js
debug - client authorized
info - handshake authorized 1385647068766475337
debug - setting request GET /socket.io/1/websocket/1385647068766475337
debug - set heartbeat interval for client 1385647068766475337
warn - websocket connection invalid
This doesn't make sense to me because I didn't touch anything with socket.io and I am using the latest chrome version (23) which I know supports websockets (I am able to successfully connect to them with PHP-Websockets). It continues to use XHR instead, but I am really interested in getting the Websocket functionality working.
2.) When I go to localhost:8080 to connect to the chat server, it takes around 7-8 seconds for it to prompt me for my name and actually connect me to the server. I have a feeling this may be because it is reverting to XHR, but I don't really know much about it so I can't say. Any thoughts?
I saw this behaviour when using an older version of socket.io with later chrome builds (and other browsers also). It would timeout then fallback to xhr polling. To check your version of the socket.io library you are using, at your shell (linux/unix) type:
npm ls| grep socket.io
And it should tell you the version. The latest at this time is 0.9.13, which works.
If you are running the tutorial from http://psitsmike.com note that the package.json file hardcodes an older version of socket.io which doesn't work with the latest browsers.
Hope this helps.
I too was facing similar issues.
Your case -
Try deleting your cookies, sometimes the xhr-polling option once connected successfully is saved to cookies and reused every next time. Similar question answered here
Also debug - served static /socket.io.js sometimes come when the socket.io file is referred incorrectly inside the html or jade template file. Try correcting the script src link in case it wrong. It should be something like - var socket = io.connect('http://localhost:3000'); OR you can also try removing the link all together like this - var socket = io.connect();
Hope it helps.
I had the exact same issue. this might be old. but My setup is on digitalocean. what happens is that usually people who run node apps on one server use nginx for the port listen and node under its own dedicated port. nginx did not forward the websocket port to the node, only port 80 which nodejs was not initialised to begin with.
http://nginx.org/en/docs/http/websocket.html
You need to make sure your nginx is configured properly for this.
I just added the port to the io.connect directly connecting to the node server and avoiding nginx.

nodejs socket.io with IIS Node

I have tried something with node.js in windows vista/IIS 7 using iis node. My idea is to use a server script on the asp .net mvc application to connect to another socket server and serve requests on a persistent fashion.
I downloaded the iisnode version at https://github.com/tjanczuk/iisnode for IIS 7 and able to run the basic 'hello world' http server pipe using http handler mappings in web.config and IIS modules configuration.
I am trying to use socket.io library from node.js. This works independently if I write a server and client. But fails when used with IIS node.
I am having problems going down further. Problems like
How to include the npm modules in the asp .net mvc project? I tried
putting the node_modules in the folder of node scripts, but that did
not help. Basically the require('socket.io') command works, but the
socket connection etc., simply fails.
How to have a socket
connection from client which will keep listening for updates from
server(like COMET) - As I said I am trying to use socket.io
Any body tried this before?
Reading back a few months ago, WebSocket support is not supported with Socket.IO under IIS, however long polling is.
This was a few months ago, and I'm running up against the same issue now and trying to resolve.
As Tomasz writes:
Please note that iisnode does not support websocket transport, but
using socket.io is still possible with other HTTP-based transports
like HTTP long polling:
io.configure(function() {
io.set('transports', ['xhr-polling']);
});
By the looks of it, as of Feb 23, 2012, this functionality is still not supported.
Do you need to go through IIS? Do you have the option of going with a pure Socket.IO/Node option, eliminating IISNode? If you need full WebSocket support with fallback capability, this looks like the only option, unless there are other suggestions?
This may or may not be related to your problem. I haven't done much with socket.io, however I was planing to do something very similar to what you're describing. When reading through the source for iisnode, I found the following code in cnodehttpmodule.cpp:
this->applicationManager->GetEventProvider()->Log(L"iisnode received a new http request", WINEVENT_LEVEL_INFO);
// reject websocket connections since iisnode does not support them
// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17#page-17
PCSTR upgrade = pHttpContext->GetRequest()->GetHeader(HttpHeaderUpgrade, NULL);
ErrorIf(upgrade && 0 == strcmp("websocket", upgrade), ERROR_NOT_SUPPORTED);
It looks to me as though if "websocket" is included in the header of the request, it will be rejected. I would need to read up on the websocket protocol to better understand exactly what this means.
I'll be the first to admit that I don't know overly well how websockets differ from a long running request. As I understand it, however, socket.io will work on older browsers that do not support websockets.
I recommend you try to set the transport to just xhr-polling or jsonp-polling. It kinda defeats the cool factor of using node.js but it might help you reach a resolution to your problem.
If your socket.io web application is hosted in an IIS virtual directory, socket.io configuration must be modified compared to a self-hosted case. Please see http://tomasz.janczuk.org/2013/01/hosting-socketio-websocket-apps-in-iis.html for details.
Also, as of version 0.2.x, iisnode does support WebSockets on Windows 8 and Windows Server 2012 with IIS 8. Check out http://tomasz.janczuk.org/2012/11/how-to-use-websockets-with-nodejs-apps.html for details.

Resources