Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebSocket connection failed: Error during WebSocket handshake: Unexpected response code: 400

I am trying to integrate Socket.io with Angular and I'm having difficulties making a connection from the client-side to the server. I've looked through other related questions but my issue is happening locally, so there's no web server in the middle.

This is what my server code looks like:

const app = express(); const server = http.createServer(app); const io = require('socket.io').listen(server);  io.on('connection', function(socket) {   socket.emit('greet', { hello: 'Hey, Mr.Client!' });    socket.on('respond', function(data) {     console.log(data);   });   socket.on('disconnect', function() {     console.log('Socket disconnected');   }); }); 

I'm loading the client side JavaScript files using Grunt in the following order:

dist: {     src: [         public/bower_components/angular/angular.min.js,         ...         public/bower_components/socket.io-client/dist/socket.io.min.js,         public/bower_components/angular-socket-io/socket.min.js,         ...     ] } 

Then in my controller:

function MyController($scope) {      let socket = io.connect(window.location.href);     socket.connect('http://localhost:3000');     socket.on('greet', function(data) {       console.log(data);       socket.emit('respond', { message: 'Hello to you too, Mr.Server!' });     });      ... } 

Before actually using the btford/angular-socket-io library, I want to make sure that I can get a connection correctly, but I get the following error in the console:

socket io connection error message

The interesting thing is that if I restart the Node.js server process, it does manage to send the message but using polling instead of websockets.

after restart

polling message

I tried all sorts of different options in the socket.connect call, but nothing worked.

Any help would be appreciated.


UPDATE (30/12/2016):

I just realized that websockets is working partially. I see a 101 Switching Protocols request in the Chrome developer console. However the only frames I see there are the engine.io protocol packets (ping, pong). However my application socket messages still fall back to polling for some reason...

engine.io packets

like image 348
ashe540 Avatar asked Dec 29 '16 14:12

ashe540


People also ask

Why do WebSockets fail?

The error event is fired when a connection with a WebSocket has been closed due to an error (some data couldn't be sent for example).

What is WebSocket handshake?

WebSockets - Overview In computer science, handshaking is a process that ensures the server is in sync with its clients. Handshaking is the basic concept of Web Socket protocol. The following diagram shows the server handshake with various clients −

What is WebSocket connection?

WebSocket is a communications protocol for a persistent, bi-directional, full duplex TCP connection from a user's web browser to a server. A WebSocket connection is initiated by sending a WebSocket handshake request from a browser's HTTP connection to a server to upgrade the connection.


2 Answers

Problem solved! I just figured out how to solve the issue, but I would still like to know if this is normal behavior or not.

It seems that even though the Websocket connection establishes correctly (indicated by the 101 Switching Protocols request), it still defaults to long-polling. The fix was as simple as adding this option to the Socket.io connection function:

{transports: ['websocket']} 

So the code finally looks like this:

const app = express(); const server = http.createServer(app); var io = require('socket.io')(server);  io.on('connection', function(socket) {   console.log('connected socket!');    socket.on('greet', function(data) {     console.log(data);     socket.emit('respond', { hello: 'Hey, Mr.Client!' });   });   socket.on('disconnect', function() {     console.log('Socket disconnected');   }); }); 

and on the client:

var socket = io('ws://localhost:3000', {transports: ['websocket']}); socket.on('connect', function () {   console.log('connected!');   socket.emit('greet', { message: 'Hello Mr.Server!' }); });  socket.on('respond', function (data) {   console.log(data); }); 

And the messages now appear as frames:

working websockets

This Github issue pointed me in the right direction. Thanks to everyone who helped out!

like image 84
ashe540 Avatar answered Oct 12 '22 23:10

ashe540


This worked for me with Nginx, Node server and Angular 4

Edit your nginx web server config file as:

server { listen 80; server_name 52.xx.xxx.xx;  location / {     proxy_set_header   X-Forwarded-For $remote_addr;     proxy_set_header   Host $http_host;     proxy_pass         "http://127.0.0.1:4200";     proxy_http_version 1.1;     proxy_set_header   Upgrade $http_upgrade;     proxy_set_header   Connection "upgrade"; } 
like image 44
Abhijeet Avatar answered Oct 12 '22 22:10

Abhijeet