Socket.io: アイドリング中にスローされるJS例外(WebSocketはすでにCLOSINGまたはCLOSED状態になっています)。

作成日 2018年05月26日  ·  55コメント  ·  ソース: socketio/socket.io

あなたはしたい:

  • [x]バグを報告する
  • []機能をリクエストする

現在の動作

ソケットを接続したまま、プログラムで他のアクティビティを実行していないときに、socket.io機構の内部(具体的にはbacko2/index.jsの83行目)からブラウザーコンソールで例外がスローされることが断続的に(ただしかなり一貫して)表示されます。そのエラーは次のとおりです。

WebSocket is already in CLOSING or CLOSED state.

socket-io-errors

再現手順(現在の動作がバグの場合)

httpsを介して同じサーバー(localhost)に接続されたクライアントソケットで2つのタブを開いています。 両方のクライアントはアイドル状態にあり、ブラウザーまたはサーバーで他に何も起きていません(keep-alive pings socket.ioが実行しているものを除く)。 それらの両方が単一のチャネルに結合されます(サーバー上のjoin(..)を介して)。 そうでなければ、他に特別なことは何もありません。

サーバーソケットインスタンスを作成する方法は次のとおりです。

var httpsServer = https.createServer(..);
var io = require("socket.io")(httpsServer);
io.on("connection",onSocketConnection);

そしてクライアントでは:

socket = io();
socket.on("connect",function(){
   console.log("socket connected");
});
socket.on("disconnect",function(){
   console.log("socket disconnected");
});

期待される動作

時々切断と再接続を期待しますが、接続を介して他に何もしていないときにライブラリによってスローされる偽のJS例外は期待していません。

設定

  • OS:Mac OSX
  • ブラウザ:Chrome 66、ノード10.2.1
  • socket.ioバージョン:2.1.1

その他の情報(スタックトレース、関連する問題、修正方法の提案など)

拡張されたスタックトレース:

index.js:83 WebSocket is already in CLOSING or CLOSED state.
(anonymous) @ index.js:83
e.encodePacket @ index.js:83
(anonymous) @ index.js:83
r.write @ index.js:83
r.send @ index.js:83
r.flush @ index.js:83
r.sendPacket @ index.js:83
r.ping @ index.js:83
(anonymous) @ index.js:83
setTimeout (async)
r.setPing @ index.js:83
r.onPacket @ index.js:83
(anonymous) @ index.js:83
r.emit @ index.js:83
r.onPacket @ index.js:83
r.onData @ index.js:83
ws.onmessage @ index.js:83

最も参考になるコメント

デフォルトのpingTimeoutが60000(v2.0.4)から5000(v2.1.0+)に変更されました。これは、Chromeなどの一部のブラウザーには不十分です。

最新のv2.2.0を含むv2.1.0+でのこの問題の解決策は、サーバーのデフォルトのpingTimeoutを次のように大きな値にオーバーライドすることです。

const http = require('http');
const server = http.createServer();
const io = require('socket.io')(server, {
  pingTimeout: 60000,
});

また

const io = require('socket.io')();
const http = require('http');
const server = http.createServer();
io.attach(server, {
  pingTimeout: 60000,
});

全てのコメント55件

まったく同じ問題が発生し、コードは正しいです。 これは私にとってChromeでのみ発生します。 Mozillaはクリーンです。 Chromeでは、このエラーは何度も雨が降り、私が持っているすべてのチャットを複製しています。 この方法を使ってみました
socket.on('disconnect', () =>{ socket.disconnect(); });
クライアントをサーバーから切断しません。 必要な場合のリポジトリhttps://github.com/antoniab123456/Chat_app

ここで同じ問題
image

ブラウザがアイドリングしているだけで、エラーが発生します。

ChromeとMacOSを使用しました

はい、誰かがそれに対処できますか? おそらく、それを修正するために別のコード行が必要ですか?

私はsocket.ioとChromeで同じ問題を抱えています
Mac OS 10.13.5
Chromeバージョン67.0.3396.87(公式ビルド)(64ビット)
ノード:10.3.0
Express:4.16.3
socket.io:2.1.1

Firefoxではすべてが正常です。

以下のエラーの詳細:

index.js:83 WebSocket is already in CLOSING or CLOSED state.
(anonymous) | @ | index.js:83
  | e.encodePacket | @ | index.js:83
  | (anonymous) | @ | index.js:83
  | r.write | @ | index.js:83
  | r.send | @ | index.js:83
  | r.flush | @ | index.js:83
  | r.sendPacket | @ | index.js:83
  | r.ping | @ | index.js:83
  | (anonymous) | @ | index.js:83
  | setTimeout (async) |   |  
  | r.setPing | @ | index.js:83
  | r.onPacket | @ | index.js:83
  | (anonymous) | @ | index.js:83
  | r.emit | @ | index.js:83
  | r.onPacket | @ | index.js:83
  | r.onData | @ | index.js:83
  | ws.onmessage | @ | index.js:83

index.js:83をクリックすると、次のモジュールに移動します。

/**
 * Expose `Backoff`.
 */

module.exports = Backoff;

/**
 * Initialize backoff timer with `opts`.
 *
 * - `min` initial timeout in milliseconds [100]
 * - `max` max timeout [10000]
 * - `jitter` [0]
 * - `factor` [2]
 *
 * <strong i="16">@param</strong> {Object} opts
 * <strong i="17">@api</strong> public
 */

function Backoff(opts) {
  opts = opts || {};
  this.ms = opts.min || 100;
  this.max = opts.max || 10000;
  this.factor = opts.factor || 2;
  this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;
  this.attempts = 0;
}

/**
 * Return the backoff duration.
 *
 * <strong i="18">@return</strong> {Number}
 * <strong i="19">@api</strong> public
 */

Backoff.prototype.duration = function(){
  var ms = this.ms * Math.pow(this.factor, this.attempts++);
  if (this.jitter) {
    var rand =  Math.random();
    var deviation = Math.floor(rand * this.jitter * ms);
    ms = (Math.floor(rand * 10) & 1) == 0  ? ms - deviation : ms + deviation;
  }
  return Math.min(ms, this.max) | 0;
};

/**
 * Reset the number of attempts.
 *
 * <strong i="20">@api</strong> public
 */

Backoff.prototype.reset = function(){
  this.attempts = 0;
};

/**
 * Set the minimum duration
 *
 * <strong i="21">@api</strong> public
 */

Backoff.prototype.setMin = function(min){
  this.ms = min;
};

/**
 * Set the maximum duration
 *
 * <strong i="22">@api</strong> public
 */

Backoff.prototype.setMax = function(max){
  this.max = max;
};

/**
 * Set the jitter
 *
 * <strong i="23">@api</strong> public
 */

Backoff.prototype.setJitter = function(jitter){
  this.jitter = jitter;
};




//////////////////
// WEBPACK FOOTER
// ./~/backo2/index.js
// module id = 41
// module chunks = 0

83行目は次のとおりです。

this.jitter = jitter;

backo2.jsと83行目で同じ問題が発生しています。エラーは次のとおりです。
index.js:83 Uncaught TypeError:'FileReader'で'readAsArrayBuffer'を実行できませんでした:パラメーター1はタイプ'Blob'ではありません。
nで(index.js:83)
nで(index.js:83)
nで(index.js:83)
nで(index.js:83)
nで(index.js:83)
nで(index.js:83)
Object.e.removeBlobs(index.js:83)で
at s(index.js:83)
r.encode(index.js:83)で
r.packet(index.js:83)で
他のものについては心配しないでください。それらはすべて83行目にあります。これはthis.jitter = jitter;です。
グーグルには本当に解決策がないので、それは私をとても苛立たせます。

誰かが一時的な解決策を見つけましたか? @ antoniab123456チャットが重複しないように、チャットアプリを修正できましたか? それは私にも同じことをしています。

設定
OS:Mac OSX
ブラウザ:Chrome 67.0.3396.99(公式ビルド)(64ビット)
ノードv10.5.0
Socket.io v2.1.1

私はクロムで言及された@getifyの正確な問題に直面しています。 誰かがこれの回避策を見つけましたか?

同じ問題。 誰かがこれに応答できますか?

同じ問題。

設定
OS:Mac OSX
ブラウザ:Chrome 67.0.3396.99(公式ビルド)(64ビット)、ノード9.6.1
socket.ioバージョン:2.1.1

@ 19smitgr idk 「重複したチャット」の意味はトピックから外れているように聞こえますが、「同じ画面にメッセージが重複している」という意味の場合は、代わりにブロードキャストすることで解決できます。

@kino2007チャットアプリケーションを作成していません。 私は実際にマルチプレイヤーゲームでWebSocketを使用していますが、WebSocketに切断メッセージが表示されなかったため、誰もが話しているランダムエラーのためにユーザーが切断して再接続すると、キャラクターに新しいソケットIDが与えられます。また、古いソケットIDを持つ古いスプライトは、「切断」メッセージではなく「トランスポートクローズ」メッセージを受け取っていたため、削除されませんでした。

この時点で、「トランスポートクローズ」メッセージが表示されても、「切断」メッセージが表示された場合と同じ方法で、現在のユーザーのリストからユーザーを削除します。

ここで同じエラー

簡単に検索したところ、 backo2がエラーの原因であることがわかりました。

次に、devバージョンのsocket.ioを使用したところ、Socket.prototype.oneventがエラーをスローすることがわかりました。

私は私のためにそれを修正しました:

以前私はこれを使用しました:

socket.on('ping', alert);

しかし、それから私はそれをこれに変更しました:

socket.on('ping', msg => {
    alert(msg);
});

そしてそれはうまくいきました!

私も同じ問題を抱えています。 これに関する更新はありますか?

こっちも一緒。

socket.io&socket.io-client: "^ 2.1.1"
マックOS
GoogleChromeは最新です
バージョン68.0.3440.106(公式ビルド)(64ビット)

私は同じ問題を抱えています。 また、サーバーからクライアントに送信するメッセージが重複しています。

screen shot 2018-08-30 at 4 51 49 pm

MacOS:10.13.6
Socket.io: "^ 2.1.1"
Chrome:68.0.3440.106

@abhyuditjain socket.removeAllListeners();を使用してすべてのリスナーをリセットして、メッセージの重複を引き起こす可能性のある複数のリスナー登録を回避することができます。

これは何人かの人々にとって進行中の問題のようであり、これに対する解決策はありませんでした。 誰かからの更新はありますか?

@vkotuすべてのリスナーを削除すると、切断時にソケットがサーバーに再接続されません。 これを修正する方法はありますか?

websocket- nodeを使用するだけで、使いやすく、エラーなしで機能します。さらに、そのための外部ライブラリは必要ありません。
https://codeburst.io/why-you-don-t-need-socket-io-6848f1c871cd
https://medium.com/@martin.sikora/node -js-websocket-simple-chat-tutorial-2def3a841b61
https://www.npmjs.com/package/websocket

広告ではなく、このエラーの決定がない限り、ただ助けてください:DDDそれは何ヶ月も続いています05.09.2018、13:15、 "Abhyudit Jain" [email protected] :@antoniab123456このページはこれに関する問題を投稿するためのものですリポジトリ。 ここで宣伝しないでください。

-言及されたため、これを受け取っています。このメールに直接返信するか、GitHubで表示するか、スレッドをミュートしてください。

-よろしくお願いいたします。アントニアB.カスタマーケアスペシャリスト@amoCRMグローバル

2.0.3にダウングレードすると、この問題が「修正」されました。

@cozuyaはそれをテストするつもりです。 それがうまくいったかどうかあなたに知らせます!

2.0.3にダウングレードすると、この問題が「修正」されました。

トリックをしているようです。 4分間テストし、エラーはありません。 それがどれくらい続くか見てみましょう!

@cozuyaこれを投稿してくれてありがとう!

2.1.1でも同じエラー

2.0.3にダウングレードすると、この問題が「修正」されました。

2.0.3は私のために働きます! ありがとう@cozuya

2.1.1まだ同じ問題に直面しています。 pingとタイムアウトを増やしようとしましたが、何も変更されませんでした

ブラウザが長時間(約20〜30分)アイドリングしているときに、v2.1.1のChromeで同じ問題が発生する

2.1.1まだ同じ問題に直面しています。 pingとタイムアウトを増やしようとしましたが、何も変更されませんでした

v2.0.3へのダウングレード

2.0.4でsocket.ioを使用しようとしましたが、正常に見えます。

pingTimeoutが60000(v2.0.4)から5000(v2.1.1)に変更されていることがわかりました。

pingTimeoutを10000sのような大きな数値に変更した場合、それは機能しているようです。

非アクティブなタブにスロットルがあるブラウザのアイドル状態に関連している可能性があります。

問題が発生しました。誰かが問題を解決しましたか?

私もダウングレードしなければなりませんでした。 クロームとサファリでは機能しませんでした

ここでも同じ問題があります。 OSXでのChrome。

socket.removeAllListeners();ではなく、$#$ "disconnect" socket.off("whatever")を使用して回避します。 正常に動作します。 ブラウザコンソールのエラーメッセージは煩わしいですが、私にとってはダウングレードする価値はありません。

何の注意も払わずにこの問題を見るのは残念だと言わざるを得ません。 それは6ヶ月と数えています。

したがって、再接続の理由は、pingタイムアウトです。 ダウングレードしてもエラーが発生します。

私は、広範なコードベースを備えたこのような巨大なライブラリに完全に同意しますが、この問題には注意を払っていません。

誰かがすぐにそれに到達することを願っています!

私のiPhoneから送信された

2018年11月28日午後2時14分、 HorseBadortiesnotifications @github.comは次のように書いています。

ここでも同じ問題があります。 OSXでのChrome。

私はsocket.removeAllListeners();を使用せずにそれを回避します。 ただし、「disconnect」などを除くすべての非技術的なリスナーの場合は、socket.off( "whatever")。 正常に動作します。 ブラウザコンソールのエラーメッセージは煩わしいですが、私にとってはダウングレードする価値はありません。

何の注意も払わずにこの問題を見るのは残念だと言わざるを得ません。 それは6ヶ月と数えています。


コメントしたのでこれを受け取っています。
このメールに直接返信するか、GitHubで表示するか、スレッドをミュートしてください。

同じ問題....これに対する修正がまだ行われていないことに驚いています。

私はこの問題に遭遇しました。 私の場合、切断はping timeoutが原因でした。 ただし、クライアント側がpingへの応答を停止した理由はわかりません。

io.on('connection', function(socket) {
  socket.on('disconnect', function(reason) {
  console.log(`Socket disconnected for: ${reason}`);
  }
});

https://socket.io/docs/server-api/#Event-%E2%80%98disconnect%E2%80%99には、切断の理由のリストがあります。

その他のデバッグ:
image
1つの観察結果は、クライアントのpingイベントが最後から+30sであるということです。 切断を確認するたびに、デフォルトのハートビート間隔+pingタイムアウトである30s+た。 +26s+28s 、および+29sは、切断せずに表示されました。
Safariと比較すると、Safariは25sごとにpingを実行する際の一貫性が高く、切断は見られませんでした。

デフォルトのpingTimeoutが60000(v2.0.4)から5000(v2.1.0+)に変更されました。これは、Chromeなどの一部のブラウザーには不十分です。

最新のv2.2.0を含むv2.1.0+でのこの問題の解決策は、サーバーのデフォルトのpingTimeoutを次のように大きな値にオーバーライドすることです。

const http = require('http');
const server = http.createServer();
const io = require('socket.io')(server, {
  pingTimeout: 60000,
});

また

const io = require('socket.io')();
const http = require('http');
const server = http.createServer();
io.attach(server, {
  pingTimeout: 60000,
});

5000では不十分なのはなぜですか? ローカル開発サーバーでこの問題が発生しており、クライアントとサーバー間の遅延は間違いなくそのしきい値を下回っています。 5000msは妥当なタイムアウトのようです。 ピンポンシステム自体に問題がある可能性があるようなにおいがし、それが下がったときにのみ現れました。

このスレッドを開始するためのThx@getify (私はsocket.io v2.2.0を使用しています)

これも経験している人には-私もコメントは助けになりません:-)あなたのサポートを示すために親指で問題に投票してください👍

pingTimeoutを発見してくれたThx @omardomaと私は、 ping/pongイベントシステムを調査する必要があるという@LunarMistに同意します。

Chrome、Firefox、Safari(すべてMacOS)で予備テストを行いました。

ChromeSafariはどちらも、動作と制約が異なるwsアクティビティを抑制しているように見えます。

  • Chrome、タブがフォーカスされたとき、またはタブがバックグラウンドに入ったとき、約5分間非アクティブになった後。 これはクロムチームによる意図的なものです(https://developers.google.com/web/updates/2017/03/background_tabs)
  • Safari、アプリのフォーカスが別のデスクトップアプリ(MacOS)に変更されたとき、またはタブがバックグラウンドに移行したとき。 #2924に関連
  • Firefox、*このスレッドで言及されている問題はありません

ソリューション

pingTimeoutpingIntervalの値を変更して、これら3つのブラウザーすべてで数時間テストしました。 私が解決策であるとわかったもの:

  1. pingTimeout > = 30000ミリ秒の設定

    • また -

  2. pingInterval <= 10000ミリ秒の設定

pingTimeout = 30000を変更するのが最善の解決策だと思います。 デフォルトのpingInterval25000 msであり、クライアントがサーバーにpingを実行する頻度を10秒ごとに増やすと、プロジェクトの規模が大きくなりすぎる可能性があります。


@darrachequesneまたは他のリポジトリメンバーは、v2.1で60000から変更された現在のデフォルトの5000 msからデフォルトのpingTimeout30000に増やすことに賛成ですか? 60000ミリ秒?

あなた自身のコメントに反応することも助けにはなりません。

クライアントはサーバーにpingを実行するクライアントであり、その逆ではありません。

これは、socket.ioの現在のバージョンがクライアント側のsetTimeoutに依存しているためだと思います。これは、期待したほど信頼性が高くない可能性があります。

pingTimeoutを増やすと一時的に問題が解決すると思いますが、v3ではサーバー->クライアント(現在のクライアント->サーバーではなく)からのping/pongを使用します。

クライアント側で次のコードを使用するだけです。

_socket.on('ping'、()=> {
socket.emit(data);
}); _

ありがとう@crobinson42! pingタイムアウトソリューションは私にとってうまく機能しました。 私はその解決策についていくつかの懸念を抱いています。 いずれかの瞬間にインターネット接続が失われた場合、切断イベントが発生するまでに最大30秒かかります。一部のアプリでは、それは長すぎます。 たとえば、ユーザーが接続していないときにテキスト入力を無効にしたいチャットアプリ。

この場合、ping間隔を長くすると作業は完了しますが、おっしゃるように、コストが高くなりますが、これに対する回避策はありますか?

これが修正されたら、私にとって同じ問題、以下の私のバージョンrをお知らせください。

"socket.io": "2.2.0",
"socket.io-adapter": "~1.1.1",
"socket.io-client": "2.2.0",
"socket.io-parser": "~3.2.0",
"socket.io-redis": "^5.2.0",

私のコード:
サーバー、{
パス:'/socket.io'、
serveClient:true、
//以下はengine.IOオプションです
pingInterval:40000、
pingTimeout:25000、
upgradeTimeout:30000、//デフォルト値は10000msです。20k以上に変更してみてください
エージェント:false、
クッキー:false、
requireUnauthorized:false、
reconnectionDelay:1000、
reconnectionDelayMax:5000
}

私の顧客:

再接続:true、
reconnectionDelay:1000、
reconnectionDelayMax:5000、
reconnectionAttempts:Infinity、
//サイトオプション
トランスポート:["polling"、 "websocket"]、
安全:本当、
requireUnauthorized:false、
forceNew:true、
タイムアウト:60000

こんにちはファイザン、
このコードを次のように実行できます-
**私はあなたから与えられたものと同じバージョンを使用しました。

サーバー側-コード:

const server = require('http')。createServer();
const io = require('socket.io')(server、{
//パス:'/socket.io'、
serveClient:true、

pingInterval: 40000,
pingTimeout: 25000,
upgradeTimeout: 21000, // default value is 10000ms, try changing it to 20k or more
agent: false,
cookie: false,
rejectUnauthorized: false,
reconnectionDelay: 1000,
reconnectionDelayMax: 5000

});

io.on('connection'、function(socket){
socket.emit('welcome'、{メッセージ:'Welcome!'、id:socket.id});
socket.on('Sunil'、console.log);
});

server.listen(3000);

クライアントサイドコード:

var client = require( "socket.io-client");
var socket = client.connect( "http:// localhost:3000"、{
再接続:true、
reconnectionDelay:1000、
reconnectionDelayMax:5000、
reconnectionAttempts:Infinity、
トランスポート:["websocket"]、
安全:false、
requireUnauthorized:false、
forceNew:true、
タイムアウト:6000
});

socket.connect();
socket.emit('Sunil'、{
データ:「こんにちは」
});
socket.on('welcome'、function(data){
console.log(data)
socket.emit('Sunil'、{
データ:「ファイザン」、
id:data.id
});

socket.disconnect();

});

よろしく
スニル・ヤダフ

2019年5月9日午後4時5分、 FaizanZahidnotifications @github.comは次のように書いています。

再接続:true、
reconnectionDelay:1000、
reconnectionDelayMax:5000、
reconnectionAttempts:Infinity、
//サイトオプション
トランスポート:["polling"、 "websocket"]、
安全:本当、
requireUnauthorized:false、
forceNew:true、
タイムアウト:60000

問題が修正されるまで誰かが興味を持っている場合は、おそらくクライアント側での回避策です。 これにより、ブラウザがメモリを解放せず、過度のメモリ使用量が発生する可能性があります。

  • ここにリストされているように、 https://apple.stackexchange.com/questions/344183/safari-12-mac-does-includeinternaldebugmenu-1-still-work 、最初にターミナルアプリにローカルでフルディスクアクセスを許可し、ターミナルを再起動します。
  • ターミナルウィンドウを開き、コマンドdefaults write com.apple.Safari IncludeInternalDebugMenu 1を貼り付けて実行します
  • Safariを再起動します。 右上に新しいデバッグメニューが表示されます。
  • [デバッグ]->[その他のフラグ]で、[アプリの仮眠を無効にする]と[非表示のページタイマーのスロットリングを無効にする]の2つのフラグを有効にして、Safariを再起動します。

誰かがChromeの回避策を持っているなら、それは助けになるでしょう

ローカルホストwebdevにSafariを使用していますか? 🤔

ローカルホストwebdevにSafariを使用していますか? 🤔

実際にはそうではありませんが、アプリをテストするために絶えず切断されるのは面倒です。 これにより、3.0で修正されるまで一時的な回避策が提供されます。 これは解決策ではありません。 それが開発中に誰かを助けるかどうか私は投稿しました。

非常に低いpingIntervalとpingTimeoutsを使用してリアルタイムのオフラインステータス変更を取得しています。30秒に設定するとフローが中断します...この問題を解決する方法を知っている人はいますか?バックグラウンドブラウザに長いタイムアウトの「修正」を使用できますタブ?

これに関する更新はありますか?

非常に低いpingIntervalとpingTimeoutsを使用してリアルタイムのオフラインステータス変更を取得しています。30秒に設定するとフローが中断します...この問題を解決する方法を知っている人はいますか?バックグラウンドブラウザに長いタイムアウトの「修正」を使用できますタブ?

プレゼンスを処理するには、ソケットの切断イベントである必要があります。ソケットが切断されたら、ユーザーを見つけて、データストアでオフラインとしてマークします。

ドキュメントのデフォルトは次のとおりです。 pingは25秒ごとに送信され、各pingは5秒で完了するようです。

pingTimeout | 5000 | 接続が閉じていると見なすためのポンパケットなしのミリ秒数
-| -| -
pingInterval | 25000 | 新しいpingパケットを送信するまでのミリ秒

私はこれと同じエラーに気づきましたが、コンテキストが異なるので、ここで終わる他の人のために、私の問題と解決策について簡単に説明します。

私のシナリオはChromeforAndroidで、画面をロックした後に接続が切断されました。

トークンを使用して、異なる接続間で同じユーザーを識別しています。これは、クエリオプションのアプローチを使用して接続時にクライアントから送信し、サーバーから受信した新しいトークンでトークンを更新します。

// client
io('myAppUrl', {
  query: {
    token: localStorage.getItem('myKey') || ''
  }
});

io.on('reconnect_attempt', () => {
  io.opts.query = {
    token: localStorage.getItem('myKey') || ''
  };
});

io.on('my_custom_connection_successful_event', (token) => {
  localStorage.setItem('myKey', token);
});

問題は、ChromeforAndroidクライアントが再接続時に空の文字列トークンをサーバーに送信することです。 localStorageから最新のトークンを確実に設定する'reconnect_attempt'リスナーを追加したので、これは予期していませんでした。

考えられるすべてのクライアントイベントをコンソールログに記録して数時間デバッグした後、再接続のシナリオでは'reconnect_attempt'イベントがまったく発生しないことに気付きました。 画面のロックを解除すると、次の一連のイベントが発生します。

  • 切断(理由:'トランスポートクローズ')
  • 再接続(試行:1)
  • 再接続
  • ping/pongが再開します

したがって、 'reconnect_attempt'イベントは発生しません。これは、トークンがまだ空の文字列(接続時に設定された初期値)である理由を説明しています。

簡単に言うと、私にとっての解決策は、サーバーから受け取ったカスタムの「接続成功」イベントのio.opts.queryインスタンス変数を新しいトークンですぐに更新することです。

// client
io('myAppUrl', {
  query: {
    token: localStorage.getItem('myKey') || ''
  }
});

io.on('my_custom_connection_successful_event', (token) => {
  localStorage.setItem('myKey', token);
  io.opts.query = {
    token: token
  };
});

これで、 io.opts.queryが接続およびその後のすべての再接続で使用されるインスタンス変数であることがわかりました。したがって、必要に応じてすぐに更新できます。 再接続関連のイベントを待つ必要はありません。

Withクエリオプションのドキュメントに少し誤解されているように感じます。 たぶん私はその例のユースケースを誤解しましたか? しかし、それが私のユースケースに似ている場合、 'reconnect_attempt'の例の代わりに、ドキュメントはio.opts.queryが変更可能なインスタンス変数であり、その現在の値が後続のすべての再接続で使用されることを説明できます。 したがって、たとえば'refresh_token'カスタムイベントであっても、トークンを更新するときはいつでも変更できます。 ドキュメントを改善するための良いアイデアだと思われる場合は、PRを行うことができます。

編集:
さらに調査したところ、 'reconnect_attempt'リスナーがコードの別の部分から削除されていることに気づきました...:man_facepalming:そのため、ログに表示されませんでした。 そうです、私の再接続シナリオのイベントシーケンスは実際には次のとおりです。

  • 切断(理由:'トランスポートクローズ')
  • reconnect_attempt(試行:1)
  • 再接続(試行:1)
  • 再接続
  • ping/pongが再開します

それでも、 io.opts.queryはいつでも変更できるという私の認識はまだ有効です。 :sweat_smile:

ダウングレードしても大丈夫ですか? 2.0.3をオンにしましたが、機能しないようです。

こんにちは、私は同じ種類の問題に直面していますが、2つのエラーがあります。 @omardomaソリューションを試しました。 誰か助けてもらえますか?
Os-Ubuntu 18.04
ノード-12.16.2
npm-6.14.5
socket.io-2.3.0
私のコード-

app.js

const speech = require('@google-cloud/speech');
const speechClient = new speech.SpeechClient(); // Creates a client
const environmentVars = require('dotenv').config();
const io = require('socket.io')();
const http = require('http');
const server = http.createServer();
io.attach(server, {
  pingTimeout: 60000,
});



console.log(io)



// =========================== SOCKET.IO ================================ //

io.on('connection', function (client) {
  console.log('Client Connected to server');
  let recognizeStream = null;

ejsファイル

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js" integrity="sha256-bQmrZe4yPnQrLTY+1gYylfNMBuGfnT/HKsCGX+9Xuqo=" crossorigin="anonymous"></script>
<script src="/js/client.js"></script>

jsファイル

const socket = io.connect("http://localhost:8080");

私はsocket.ioバージョン2.3.0を使用しています。 クライアントへのWebSocket接続を使用しています。 クライアントのUIにブラウザーアラート(同期)があり、ユーザーがアラートを30秒(pingTimeout + pingInterval)を超えて閉じない場合、「WebsocketはすでにCLOSINGまたはCLOSED状態になっています」というメッセージが表示され、 pingTimeout理由でイベントを切断します。 UIにアラートがあるときに、このWebSocketを切断したくありません。 pingTimeoutを10分に増やすと、切断は10分間発生しません。 しかし、上記のコメントで私が読んだことから、これは悪影響を与える可能性があります(クライアントは10分まで切断があったことを知らない可能性があります)。 しかし、ネットワークの中断などが発生した場合、トランスポートクローズの理由で切断されることに気づきました。 では、このpingTimeout + pingIntervalを増やしても大丈夫ですか? 切断が検出されない場合の特定のシナリオはありますか? または、これを修正する他の方法はありますか?

このページは役に立ちましたか?
0 / 5 - 0 評価