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

后端 未结 16 1443
攒了一身酷
攒了一身酷 2020-12-04 21:08

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 quest

相关标签:
16条回答
  • 2020-12-04 21:29

    if you are using httpd/apache, you can add a file something like ws.conf and add this code to it. Also, this solution can proxy something like this "http://localhost:6001/socket.io" to just this "http://localhost/socket.io"

    <VirtualHost *:80>
        RewriteEngine on
    
        #redirect WebSocket
        RewriteCond %{REQUEST_URI}  ^/socket.io            [NC]
        RewriteCond %{QUERY_STRING} transport=websocket    [NC]
        RewriteRule /(.*)           ws://localhost:6001/$1 [P,L]
    
        ProxyPass        /socket.io http://localhost:6001/socket.io
        ProxyPassReverse /socket.io http://localhost:6001/socket.io
    </VirtualHost>
    
    0 讨论(0)
  • 2020-12-04 21:31

    Using Apollo Server 2.

    Per https://github.com/apollographql/apollo-client/issues/4778#issuecomment-509638071, this solved my problem:

    try 'ws://localhost:4000/graphql'

    ...since incoming and outgoing requests now use the same address.

    0 讨论(0)
  • 2020-12-04 21:34

    You're using port 3000 on the client-side. I'd hazard a guess that's the Angular port and not the server port? It should be connecting to the server port.

    0 讨论(0)
  • 2020-12-04 21:35

    I had faced same issues, I refined apache2 virtual host entery and got success.

    Note: on server I had succesful installed and working on 9001 port without any issue. This guide line for apache2 only no relavence with nginx, this answer 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>
    

    Advance tips: Please with help of a2enmod enable all mod of apache2

    Restart apache2 than will get effect. But obvious a2ensite to enable site required.

    0 讨论(0)
  • 2020-12-04 21:37

    The problem for me was not got the port from process.env.PORT it is very important because Haruko and other services properly do a random port numbers to use.

    So that is the code that work for me eventuly :

    var app = require('express')();
    var http = require('http').createServer(app);
    const serverPort = process.env.PORT ; //<----- important 
    
    const io = require('socket.io')(http,{
      cors: {
        origin: '*',
        methods: 'GET,PUT,POST,DELETE,OPTIONS'.split(','),
        credentials: true
      }
    });
    
    http.listen(serverPort,()=>{
      console.log(`server listening on port ${serverPort}`)
    })
    
    0 讨论(0)
  • 2020-12-04 21:40

    The currently accepted solution is misleading.

    According to the official documentation, adding the transports: [ 'websocket' ] option effectively removes the ability to fallback to long-polling when the websocket connection can not be established. This option is what makes socket.io so robust in the first place because it can adapt to many scenarios.

    In that particular case where one wishes to solely rely on websockets, directly using the WebSocket API is recommended.

    For other cases (admittedly most users), this is most likely a reverse proxy/server configuration problem.

    The official documentation suggests the following depending on your environment:

    NginX configuration

    http {
      server {
        listen 3000;
        server_name io.yourhost.com;
    
        location / {
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header Host $host;
    
          proxy_pass http://nodes;
    
          # enable WebSockets
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "upgrade";
        }
      }
    
      upstream nodes {
        # enable sticky session based on IP
        ip_hash;
    
        server app01:3000;
        server app02:3000;
        server app03:3000;
      }
    }
    

    Apache HTTPD configuration

    Header add Set-Cookie "SERVERID=sticky.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
    
    <Proxy "balancer://nodes_polling">
        BalancerMember "http://app01:3000" route=app01
        BalancerMember "http://app02:3000" route=app02
        BalancerMember "http://app03:3000" route=app03
        ProxySet stickysession=SERVERID
    </Proxy>
    
    <Proxy "balancer://nodes_ws">
        BalancerMember "ws://app01:3000" route=app01
        BalancerMember "ws://app02:3000" route=app02
        BalancerMember "ws://app03:3000" route=app03
        ProxySet stickysession=SERVERID
    </Proxy>
    
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule /(.*) balancer://nodes_ws/$1 [P,L]
    RewriteCond %{HTTP:Upgrade} !=websocket [NC]
    RewriteRule /(.*) balancer://nodes_polling/$1 [P,L]
    
    ProxyTimeout 3
    

    HAProxy configuration

    listen chat
      bind *:80
      default_backend nodes
    
    backend nodes
      option httpchk HEAD /health
      http-check expect status 200
      cookie io prefix indirect nocache # using the `io` cookie set upon handshake
      server app01 app01:3000 check cookie app01
      server app02 app02:3000 check cookie app02
      server app03 app03:3000 check cookie app03
    

    Also worth reading this on upgrading connections in HAProxy.

    For more details please refer to the official documentation link above.

    EDIT:

    Varnish (source here)

    sub vcl_recv {
        if (req.http.upgrade ~ "(?i)websocket") {
            return (pipe);
        }
    }
    
    sub vcl_pipe {
        if (req.http.upgrade) {
            set bereq.http.upgrade = req.http.upgrade;
            set bereq.http.connection = req.http.connection;
        }
    }
    
    0 讨论(0)
提交回复
热议问题