webentwicklung-frage-antwort-db.com.de

WebSocket-Verbindung fehlgeschlagen: Fehler beim WebSocket-Handshake: Unerwarteter Antwortcode: 400

Ich versuche, Socket.io mit Angular zu integrieren, und ich habe Schwierigkeiten, eine Verbindung von der Clientseite zum Server herzustellen. Ich habe andere verwandte Fragen durchgesehen, aber mein Problem tritt lokal auf, also gibt es keinen Webserver in der Mitte.

So sieht mein Servercode aus:

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');
  });
});

Ich lade die clientseitigen JavaScript-Dateien mit Grunt in der folgenden Reihenfolge:

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,
        ...
    ]
}

Dann in meinem 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!' });
    });

    ...
}

Vor der eigentlichen Verwendung der btford/angular-socket-io-Bibliothek möchte ich sicherstellen, dass eine Verbindung korrekt hergestellt werden kann. In der Konsole wird jedoch folgende Fehlermeldung angezeigt:

 socket io connection error message

Das Interessante daran ist, dass es mir nach dem Neustart des Node.js-Serverprozesses gelingt, die Nachricht zu senden, jedoch eine Abfrage anstelle von Websockets zu verwenden.

 after restart

 polling message

Ich habe alle möglichen Optionen im socket.connect-Aufruf ausprobiert, aber nichts hat funktioniert.

Jede Hilfe wäre dankbar.


UPDATE (30.12.2016):

Ich habe gerade gemerkt, dass Websockets teilweise funktionieren. In der Chrome-Entwicklerkonsole wird eine Anforderung von 101 Switching Protocols angezeigt. Die einzigen Frames, die ich dort sehe, sind jedoch die engine.io-Protokollpakete (Ping, Pong). Meine Anwendungssocketnachrichten greifen jedoch aus irgendeinem Grund immer noch auf Abfragen zurück ...

 engine.io packets

14
ashe540

Problem gelöst! Ich habe gerade herausgefunden, wie ich das Problem lösen kann, aber ich würde trotzdem gerne wissen, ob dies normal ist oder nicht.

Es scheint, dass, obwohl die Websocket-Verbindung korrekt hergestellt wird (dies wird durch die Anforderung von 101 Switching Protocols angezeigt), der Standardwert für lange Abfragen weiterhin besteht. Das Update war so einfach wie das Hinzufügen dieser Option zur Verbindungsfunktion Socket.io:

{transports: ['websocket']}

So sieht der Code schließlich so aus:

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');
  });
});

und auf dem Kunden:

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);
});

Und die Nachrichten erscheinen jetzt als Frames:

funktionierende Websockets

Diese Github Ausgabe wies mich in die richtige Richtung. Danke an alle, die geholfen haben! 

29
ashe540

Dies funktionierte für mich mit Nginx, Node Server und Angular 4

Bearbeiten Sie die Konfigurationsdatei Ihres nginx-Webservers wie folgt:

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";
}
8
Ab.Progr

Anhand der Nachrichten, die Sie über Socket.IO socket.emit('greet', { hello: 'Hey, Mr.Client!' }); senden, wird angenommen, dass Sie die Boilerplate hackathon-starter verwenden. In diesem Fall könnte es sein, dass das express-status-monitor-Modul seine eigene socket.io-Instanz erstellt, wie folgt: https://github.com/RafalWilinski/express-status-monitor#using-modul-with-socketio-in -Projekt

Du kannst entweder:

  1. Entfernen Sie das Modul
  2. Übergeben Sie Ihre socket.io-Instanz und den Port als websocket, wenn Sie die expressStatusMonitor-Instanz wie folgt erstellen:

    const server = require('http').Server(app);
    const io = require('socket.io')(server);
    ...
    app.use(expressStatusMonitor({ websocket: io, port: app.get('port') })); 
    
7
Kuriakin Zeng

Ich habe das gelöst, indem ich die Transporte von "websocket" auf "polling" geändert habe.

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

Ich hatte die gleichen Probleme, ich verfeinerte Apache2 Virtual Host Entery und bekam Erfolg.

Hinweis: Auf dem Server war ich erfolgreich installiert und arbeitete problemlos an der 9001-Schnittstelle. Diese Leitlinie für Apache2 ist mit nginx nur nicht verwandt, diese Antwort für Apache2 + Etherpad-Liebhaber.

<VirtualHost *:80>
  ServerName pad.tejastank.com
  ServerAlias pad.tejastank.com
  ServerAdmin [email protected]

  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>

Vorab-Tipps: Bitte aktivieren Sie mit Hilfe von a2enmod alle Mods von Apache2

Starten Sie Apache2 neu, um den Effekt zu erhalten. Aber offensichtlich a2ensite, um den Standort zu ermöglichen.

1
Tejas Tank

Ich habe das gelöst, indem ich io.listen(server); entfernt habe. Dieser Fehler trat auf, als ich mit der Integration von passport.socketio und der Verwendung von Passport-Middleware begann.

0
David

Ich denke, Sie sollten Ihre origins für die Kundenseite wie folgt definieren:

//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
Saeid Alidadi

Sie verwenden clientseitig Port 3000. Ich würde raten, dass dies der Angular Port und nicht der Serverport ist? Es sollte eine Verbindung zum Serverport hergestellt werden.

0
martinedwards

In Ihrem Controller verwenden Sie ein http-Schema, aber ich denke, Sie sollten ein ws-Schema verwenden, da Sie Websockets verwenden. Versuchen Sie, ws://localhost:3000 in Ihrer Verbindungsfunktion zu verwenden.

0
TeaMonkie

Nachdem ich die folgenden Einstellungen für den Lastenausgleich verwendet habe, wurde mein Problem für wss behoben, aber für ws gibt es immer noch ein Problem für einen bestimmten ISP.

Calssic-Load-Balancer

0
Mamun Hasan