express
で実行されているsocket.io
アプリでnode.js
を使用しています。
ローカルバージョン(localhost
)のすべての単語は正常ですが、運用サーバー(カスタム証明書を使用してhttps
を介して提供される)に切り替えると、ブラウザーコンソールで次のエラーが表示されます。
websocket.js:112 WebSocket connection to 'wss://infranodus.com/socket.io/?EIO=3&transport=websocket&sid=j_WBxkPY_RlpF9_ZAANP' failed: Error during WebSocket handshake: Unexpected response code: 400
私は調査しました( ここで参照されている問題 )、アプリ/ホスティングプロバイダーがwss
のような接続をブロックし、socket.io
がAJAX
にフォールバックしてリクエストを行うため、これが起こることがわかりました(正常に機能しますが、バグがある場合があります)。
したがって、このエラーを取り除くためにアプリに変更を加えることができるかどうかを尋ねたいですか?
現在、 http://infranodus.com へのすべてのリクエストは https://infranodus.com と私のapp.js
ファイル(一部サーバーのアクティベーションは次のようになります):
var http = require('http');
var app = express();
var server = http.Server(app);
var io = require('socket.io')(server);
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
そして、フロントエンドファイルでソケットを必要とする方法:
<script src="/socket.io/socket.io.js"></script>
その後
var socket = io();
たぶん問題は、http
ではなくhttps
を使用してnode.jsアプリでサーバーをアクティブにすることです?しかし、証明書の保存場所がわからず、バックエンドコードをあまり変更したくないため、これに切り替えたくありません。
UPDATE(2018年10月21日):問題は nginxサーバーを使用 であり、一部の制限のためユーザーがnginxサーバーを編集することを許可していないホスティングプロバイダー、セキュアプロトコル上のWebSocketがブロックされるか、400エラーが発生します。多くのユーザーが抱えている問題であるため、sockets.ioでこれを解決するのは良いことです。何か案は?
問題を再現するには:Javascriptコンソールを開いて https://infranodus.com/news/english にアクセスしてください=
express-status-monitor
をExpressのミドルウェアとして使用しているかどうかを確認します。これにより、WebSocketの最初の(要求)ハンドシェイクでHTTP呼び出しが失敗します。
見て こちら このエラーの詳細
同じエラーが発生しました。
infranodus.com/socket.io/?EIO=3&transport=websocket&sid=j_WBxkPY_RlpF9_ZAANP にアクセスして、「セッションID不明」というメッセージを返すことにしました。
複数のノードを使用しましたか?この場合は、サイト https://socket.io/docs/using-multiple-nodes/ を参照してください。
公式サイトにあるように、
異なるプロセスまたはマシン間で接続の負荷を分散する予定の場合、特定のセッションIDに関連付けられたリクエストがそれらを発信したプロセスに接続することを確認する必要があります。
これは、XHRポーリングやJSONPポーリングのような特定のトランスポートが、「ソケット」の存続期間中にいくつかのリクエストを実行することに依存しているためです。スティッキーバランシングを有効にしないと、恐ろしい結果になります。
Error during WebSocket handshake: Unexpected response code: 400
説明に従ってNginxの設定を再設定し、このようにExpressを調整してみてください
let port = parseInt(your_port) + parseInt(process.env.NODE_APP_INSTANCE);
server.listen(port, console.log("Server running "+port));
それが何かを変更するかどうか教えてください:)
最初の接続には安全なURLを使用します。つまり、「http://」の代わりに「https://」を使用します。 WebSocketトランスポートが選択されている場合、Socket.IOはWebSocket接続にも自動的に「wss://」(SSL)を使用する必要があります。
Io()を呼び出すときにURLを指定しない場合、デフォルトでページを提供するホストに接続しようとするため、URLを指定するか、httpsに変更する必要があります。
var socket = io.connect('https://localhost', {secure: true}); //remote url
これがあなたのために働くなら、この2つの方法を試してください
この方法を試してください1:
私は同じ問題に直面していました。 30分デバッグした後、ALB(Application Load Balancer)スティッキネスを有効にして問題を解決しました。それは私のために働いた。
この方法を試してください2:
// Client side adding transport param:
var socket = io('http://localhost:3000', { transports: ['websocket'] });
ドメインごとにこの値「 http:// localhost:30 」を設定できます。