Failed to connect to WebSocket: WebSocket handshake error: unexpected response code: 400

I'm trying to integrate Socket.io with Angular, and I'm having difficulty connecting from the client side to the server. I looked at other related questions, but my problem happens locally, so there is no web server in the middle.

This code of my server is as follows:

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 load 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 using the btford/angular-socket-io library, I want to make sure that I can establish the connection correctly, but I get the following error in the console:

io socket connection error message

Interestingly, if I restart the Node.js server process, it will be able to send a message, but using a poll instead of websites.

after restart

poll message

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

Any help would be appreciated.


UPDATE (12/30/2016):

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

engine.io packages

+32
source share
10 answers

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

It seems that even if the Websocket connection is correctly established (indicated in request 101 of the switching protocol), it still uses a long poll by default. The fix was as simple as adding this option to the Socket.io connection function:

 {transports: ['websocket']} 

So, the code is as follows:

 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 messages are now displayed as frames:

work websites

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

+39
source

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

Change the nginx web server configuration 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"; } 
+17
source

Judging by the messages you send via Socket.IO socket.emit('greet', { hello: 'Hey, Mr.Client!' }); It looks like you are using the hackathon-starter template. If so, the problem may be that the express-status-monitor module creates its own instance of socket.io according to: https://github.com/RafalWilinski/express-status-monitor#using-module-with- socketio- in-project

You also can:

  1. Delete this module
  2. Pass your socket.io instance and port as websocket when instantiating expressStatusMonitor as expressStatusMonitor below:

     const server = require('http').Server(app); const io = require('socket.io')(server); ... app.use(expressStatusMonitor({ websocket: io, port: app.get('port') })); 
+8
source

I solved this by changing the transports from websocket to polling

  var socket = io.connect('xxx.xxx.xxx.xxx:8000', { transports: ['polling'] }); 
+3
source

I faced the same problems, I improved the apache2 virtual host process and got success.

Note. On the server, I successfully installed and worked on server 9001 without any problems. This guideline for apache2 is not related to nginx, this answer is for apache2 + etherpad lovers.

 <VirtualHost *:80> ServerName pad.tejastank.com ServerAlias pad.tejastank.com ServerAdmin snippetbucket@gmail.com LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so LoadModule headers_module /usr/lib/apache2/modules/mod_headers.so LoadModule deflate_module /usr/lib/apache2/modules/mod_deflate.so ProxyVia On ProxyRequests Off ProxyPreserveHost on <Location /> ProxyPass http://localhost:9001/ retry=0 timeout=30 ProxyPassReverse http://localhost:9001/ </Location> <Location /socket.io> # This is needed to handle the websocket transport through the proxy, since # etherpad does not use a specific sub-folder, such as /ws/ to handle this kind of traffic. # Taken from https://github.com/ether/etherpad-lite/issues/2318#issuecomment-63548542 # Thanks to beaugunderson for the semantics RewriteEngine On RewriteCond %{QUERY_STRING} transport=websocket [NC] RewriteRule /(.*) ws://localhost:9001/socket.io/$1 [P,L] ProxyPass http://localhost:9001/socket.io retry=0 timeout=30 ProxyPassReverse http://localhost:9001/socket.io </Location> <Proxy *> Options FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all </Proxy> </VirtualHost> 

Promotion Tips: Please use a2enmod to enable the whole mod of apache2

Restart apache2, than get the effect. But the obvious a2ensite to provide the desired site.

+1
source

In your controller, you are using the http scheme, but I think you should use the ws scheme as you are using websockets. Try using ws://localhost:3000 in your connection function.

0
source

I think you should define your origins for the client side below:

 //server.js const socket = require('socket.io'); const app = require('express')(); const server = app.listen('port'); const io = socket().attach(server); io.origins("your_domain:port www.your_domain:port your_IP:port your_domain:*") io.on('connection', (socket) => { console.log('connected a new client'); }); //client.js var socket = io('ws://:port'); 
0
source

You are using port 3000 on the client side. I would risk assuming that the corner port, not the server port? This should be a connection to the server port.

0
source

After using the following load balancing setting, my problem is resolved for wss, but for ws the problem still exists for a particular provider.

calssic load balancing

0
source

I solved this by deleting io.listen(server); . I started to encounter this error when I started integrating passport.socketio and using middleware for passports.

0
source

Source: https://habr.com/ru/post/1013603/


All Articles