Socket.io: تم طرح استثناءات JS أثناء الخمول فقط (WebSocket في حالة الإغلاق أو الإغلاق بالفعل.)

تم إنشاؤها على ٢٦ مايو ٢٠١٨  ·  55تعليقات  ·  مصدر: socketio/socket.io

اتريد:

  • [x] أبلغ عن خطأ
  • [] طلب ميزة

السلوك الحالي

أثناء ترك مأخذ توصيل متصل ، ولكني لا أقوم بأي نشاط آخر في برنامجي ، أرى بشكل متقطع (ولكن بشكل متسق إلى حد ما) استثناءً يتم طرحه في وحدة تحكم المتصفح ، من داخل ماكينات socket.io (تحديدًا في backo2/index.js سطر 83. هذا الخطأ هو:

WebSocket is already in CLOSING or CLOSED state.

socket-io-errors

خطوات إعادة الإنتاج (إذا كان السلوك الحالي خطأ)

لدي علامتا تبويب مفتوحتان بمآخذ توصيل للعميل متصلة بنفس الخادم (المضيف المحلي) عبر https. كلا العميلين يجلسان في وضع الخمول دون أن يحدث أي شيء آخر في المتصفح أو الخادم (باستثناء ما يفعله 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 الزائفة التي ألقتها المكتبة عندما لا أفعل أي شيء آخر على الاتصالات.

اقامة

  • نظام التشغيل: Mac OSX
  • المتصفح: Chrome 66 ، العقدة 10.2.1
  • الإصدار socket.io: 2.1.1

معلومات أخرى (مثل stacktraces والمشكلات ذات الصلة واقتراحات كيفية الإصلاح)

تتبع مكدس موسع:

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.1.0 + بما في ذلك الإصدار الأخير v2.2.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 بالنسبة لي. موزيلا نظيفة. في الكروم ، هذا الخطأ يمطر مرارًا وتكرارًا ويكرر كل الدردشات التي لدي. حاولت استخدام هذه الطريقة
socket.on('disconnect', () =>{ socket.disconnect(); });
لا يفصل العميل عن الخادم. الريبو في حالة الحاجة https://github.com/antoniab123456/Chat_app

نفس المشكلة هنا
image

المتصفح فقط في وضع الخمول ، ثم تظهر الأخطاء.

لقد استخدمت Chrome و mac OS

نعم يارفاق ، هل يمكن لشخص ما معالجة ذلك؟ ربما نحتاج إلى سطر آخر من التعليمات البرمجية لإصلاح ذلك؟

لدي نفس المشكلة مع socket.io و Chrome
نظام التشغيل Mac OS 10.13.5
إصدار Chrome 67.0.3396.87 (الإصدار الرسمي) (64 بت)
العقدة: 10.3.0
سريع: 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 خطأ في النوع غير معروف: فشل تنفيذ "readAsArrayBuffer" على "FileReader": المعلمة 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)
في s (index.js: 83)
في r.encode (index.js: 83)
في r.packet (index.js: 83)
ولا تقلق بشأن الأشياء الأخرى ، فجميعهم في السطر 83 ، وهو this.jitter = jitter;
إنه يزعجني لدرجة أنه لا يوجد أي حل في google.

هل وجد أي شخص حلا مؤقتا؟ @ antoniab123456 هل تمكنت من إصلاح تطبيق الدردشة الخاص بك بحيث لا يكرر دردشاتك؟ إنها تفعل الشيء نفسه بالنسبة لي.

اقامة
نظام التشغيل: Mac OSX
المتصفح: Chrome 67.0.3396.99 (الإصدار الرسمي) (64 بت)
العقدة v10.5.0
Socket.io v2.1.1

أواجه مشكلة getify المذكورة في الكروم. هل وجد أحد أي عمل حول هذا؟

نفس المشكلة. هل يمكن لأحد أن يرد على هذا؟

نفس المشكلة.

اقامة
نظام التشغيل: Mac OSX
المتصفح: Chrome 67.0.3396.99 (الإصدار الرسمي) (64 بت) ، العقدة 9.6.1
الإصدار socket.io: 2.1.1

@ 19smitgr أتساءل عما تقصده بعبارة "dulplicate chats" التي تبدو خارج الموضوع والتي يمكن حلها عن طريق البث بدلاً من ذلك إذا كنت تقصد "رسالة مكررة في نفس الشاشة".

@ kino2007 أنا لا أقوم بإنشاء تطبيق دردشة. أنا في الواقع أستخدم مآخذ ويب مع لعبة متعددة اللاعبين ، ولم يكن مأخذ الويب يتلقى رسالة قطع الاتصال ، لذلك عندما يقوم المستخدم بفصل وإعادة الاتصال بسبب الخطأ العشوائي الذي يتحدث عنه الجميع ، فإنه سيعطي الشخصية معرف مقبس جديد ، ولم يتم حذف الكائن القديم بمعرف المقبس القديم لأنه كان يتلقى رسالة "إغلاق النقل" بدلاً من رسالة "قطع الاتصال".

في هذه المرحلة ، حتى إذا تلقيت رسالة "إغلاق النقل" ، فأنا أحذف المستخدم من قائمة المستخدمين الحاليين بنفس الطريقة كما لو تلقيت رسالة "قطع الاتصال".

نفس الخطأ هنا

بعد بحث سريع اكتشفت أن backo2 يسبب الخطأ.

ثم استخدمت إصدار المطور من socket.io واكتشفت أن Socket.prototype.onevent يرمي الخطأ.

أصلحته لي:

سبق لي أن استخدمت هذا:

socket.on('ping', alert);

ولكن بعد ذلك قمت بتغييره إلى هذا:

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

وقد نجحت!

انا لدى نفس المشكله. أي تحديثات على هذا؟

نفس الشيء هنا.

socket.io & socket.io-client: "^ 2.1.1"
ماك
Google Chrome مُحدَّث
الإصدار 68.0.3440.106 (الإصدار الرسمي) (64 بت)

أواجه نفس المشكلة. أيضًا ، إنه تكرار للرسائل التي أرسلها من خادم إلى عميل.

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

نظام التشغيل MacOS: 10.13.6
Socket.io: "^ 2.1.1"
الكروم: 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 ، أو كتم صوت سلسلة المحادثات.

- مع خالص التقدير ، أنطونيا ب. أخصائي رعاية العملاء amoCRM العالمية

الرجوع إلى 2.0.3 "أصلح" هذه المشكلة بالنسبة لي.

cozuya ذاهب لاختباره. سوف نعلمك إذا نجحت!

الرجوع إلى 2.0.3 "أصلح" هذه المشكلة بالنسبة لي.

يبدو أنه يقوم بالمهمة. تم اختباره لمدة 4 دقائق وبدون أخطاء. دعونا نرى كم من الوقت يحمل!

cozuya شكرا لنشر هذا!

نفس الخطأ في 2.1.1

الرجوع إلى الإصدار 2.0.3 "إصلاح" هذه المشكلة بالنسبة لي.

2.0.3 يعمل بالنسبة لي! شكرا @ cozuya

2.1.1 لا تزال تواجه نفس القضايا. حاولت زيادة ping و timeout لكن لم يتغير شيء

تواجه نفس المشكلة في Chrome مع الإصدار 2.1.1 ، بينما المتصفح في وضع الخمول لفترة طويلة (حوالي 20-30 دقيقة)

2.1.1 لا تزال تواجه نفس القضايا. حاولت زيادة ping و timeout لكن لم يتغير شيء

الرجوع إلى الإصدار 2.0.3

لقد حاولت استخدام socket.io مع 2.0.4 ، يبدو طبيعيًا.

لقد وجدت أن هناك تغييرًا في pingTimeout من 60000 (v2.0.4) إلى 5000 (v2.1.1)

إذا قمت بتغيير pingTimeout إلى عدد أكبر مثل 10000s ، فيبدو أنه يعمل.

أعتقد أنه قد يتعلق بالمتصفح الخامل حيث سيكون لعلامة التبويب غير النشطة بعض الاختناق.

لدي بعض المشاكل ، هل قام أحدهم بحل المشكلة؟

اضطررت إلى الرجوع إلى الدرجة الأولى أيضًا. لم يكن يعمل مع الكروم ورحلات السفاري

نفس المشكلة هنا. Chrome ضمن OSX.

إنني أعمل على حلها بعدم استخدام socket.removeAllListeners(); ولكن socket.off("whatever") لجميع المستمعين غير التقنيين إلى جانب "disconnect" وما إلى ذلك. يعمل بشكل جيد. رسائل الخطأ في وحدة تحكم المتصفح مزعجة ولكنها لا تستحق الرجوع إلى إصدار أقدم بالنسبة لي.

يجب أن أقول إنه من المخيب للآمال رؤية هذه القضية دون أي اهتمام على الإطلاق. إنها ستة أشهر وتتزايد.

لذا فإن سبب إعادة الاتصال هو انتهاء مهلة اختبار الاتصال بالنسبة لي. حتى مع الرجوع إلى إصدار أقدم ، ما زلت أتلقى الخطأ.

أتفق تمامًا مع هذه المكتبة الضخمة ذات قاعدة الرموز الواسعة ولكن لا يوجد اهتمام بهذه المشكلة!

أتمنى أن يحصل عليها شخص ما قريبا!

مرسل من الايفون الخاص بي

في 28 تشرين الثاني (نوفمبر) 2018 ، الساعة 2:14 مساءً ، كتب موقع HorseBadorties [email protected] :

نفس المشكلة هنا. Chrome ضمن OSX.

أنا أعمل حوله لا باستخدام socket.removeAllListeners () ؛ لكن socket.off ("أيًا كان") لجميع المستمعين غير التقنيين إلى جانب "قطع الاتصال" وما إلى ذلك. يعمل بشكل جيد. رسائل الخطأ في وحدة تحكم المتصفح مزعجة ولكنها لا تستحق الرجوع إلى إصدار أقدم بالنسبة لي.

يجب أن أقول إنه من المخيب للآمال رؤية هذه القضية دون أي اهتمام على الإطلاق. إنها ستة أشهر وتتزايد.

-
أنت تتلقى هذا لأنك علقت.
قم بالرد على هذه الرسالة الإلكترونية مباشرةً ، أو اعرضها على GitHub ، أو قم بكتم صوت الموضوع.

نفس المشكلة .... فوجئت أنه لم يتم إجراء إصلاح لهذا حتى الآن.

لقد واجهت هذه المشكلة. في حالتي ، كان قطع الاتصال بسبب ping timeout . ومع ذلك ، لا حظ في سبب توقف جانب العميل عن الاستجابة للأصوات.

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
إحدى الملاحظات هي أن حدث ping على العميل هو +30s من الأخير. في كل مرة رأيت فيها قطع الاتصال ، كان 30s+ وهو الفاصل الزمني الافتراضي لنبضات القلب + مهلة ping. ظهرت +26s و +28s و +29s بدون انقطاع الاتصال.
عند المقارنة مع Safari ، كان Safari أكثر اتساقًا في تنفيذ الأمر ping لكل 25s ولم ير أي قطع اتصال.

هناك تغيير في pingTimeout الافتراضي من 60000 (v2.0.4) إلى 5000 (v2.1.0 +) وهو ليس كافيًا لبعض المتصفحات مثل Chrome.

يتمثل حل هذه المشكلة في الإصدار v2.1.0 + بما في ذلك الإصدار الأخير v2.2.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 لا يكفي؟ أرى هذه المشكلة على خادم التطوير المحلي ، ومن المؤكد أن زمن الانتقال بين العميل والخادم أقل من هذا الحد. 5000 مللي ثانية تبدو وكأنها مهلة معقولة. يمكن أن تكون هناك روائح مثل مشكلة في نظام تنس الطاولة نفسه ، ولا تظهر إلا عند خفضه.

Thx لبدء هذا الموضوع getify (أنا على socket.io v2.2.0)

لأي شخص يعاني من هذا أيضًا - تعليقات ME أيضًا لا تساعد :-) ، يرجى التصويت على المشكلة بإبهام لإظهار دعمك 👍

Thxomardoma لاكتشاف pingTimeout وأنا أتفق مع LunarMist على أنه يجب علينا التحقيق في نظام الأحداث ping/pong .

لقد أجريت بعض الاختبارات الأولية باستخدام Chrome و Firefox و Safari (جميعها على نظام MacOS).

يبدو أن كل من Chrome و Safari يخنقان نشاط ws بسلوك وقيود مختلفة:

  • Chrome ، بعد حوالي 5 دقائق من عدم النشاط عندما تكون علامة التبويب مركزة أو فورًا عندما تنتقل علامة التبويب إلى الخلفية. هذا مقصود من قبل فريق الكروم (https://developers.google.com/web/updates/2017/03/background_tabs)
  • Safari ، على الفور تقريبًا عند تغيير تركيز التطبيق إلى تطبيق سطح مكتب آخر (MacOS) أو عندما تنتقل علامة التبويب إلى الخلفية. متعلق بـ # 2924
  • Firefox ، * لم يتم ذكر أي مشاكل في هذا الموضوع مطلقًا

حلول

لقد اختبرت لعدة ساعات مع جميع هذه المتصفحات الثلاثة ، وقمت بتغيير قيم pingTimeout & pingInterval . ما وجدته من الحلول:

  1. تعيين pingTimeout > = 30000 مللي ثانية

    • أو -

  2. تعيين pingInterval <= 10000 مللي ثانية

أعتقد أن الحل الأفضل هو تغيير pingTimeout = 30000 . الافتراضي pingInterval هو 25000 مللي ثانية وزيادة تكرار العملاء الذين يقومون باختبار اتصال الخادم لكل 10 ثوانٍ يمكن أن يكون ثرثاريًا جدًا بالنسبة للمشاريع على نطاق واسع.


هل darrachequesne أو أي من أعضاء الريبو الآخرين يؤيدون زيادة القيمة الافتراضية pingTimeout إلى 30000 من القيمة الافتراضية الحالية 5000 ms التي تم تغييرها في v2.1 من 60000 مللي ثانية؟

كما أن الرد على تعليقك لا يساعد.

العملاء هم الذين يقومون باختبار اتصال الخادم وليس العكس.

أعتقد أن هذا لأن الإصدار الحالي من socket.io يعتمد على setTimeout من جانب العميل ، والتي قد لا تكون موثوقة كما هو متوقع.

أعتقد أن زيادة pingTimeout يجب أن يحل المشكلة مؤقتًا ، لكننا سنستخدم ping / pong من الخادم -> العميل (بدلاً من العميل الحالي -> الخادم) في الإصدار 3.

فقط استخدم الكود التالي في نهاية العميل.

_socket.on ('ping'، () => {
socket.emit (بيانات) ؛
}) ؛ _

شكرا لك @ crobinson42! نجح حل Ping timeout بشكل رائع بالنسبة لي. لدي فقط بعض المخاوف بشأن هذا الحل. إذا فقدت الاتصال بالإنترنت في أي لحظة ، فسوف يستغرق الأمر ما يصل إلى 30 ثانية حتى يتم إطلاق حدث قطع الاتصال وبالنسبة لبعض التطبيقات ، فهذا كثير جدًا. على سبيل المثال ، تطبيق دردشة يريد تعطيل إدخال النص عندما لا يكون المستخدم متصلاً.

في هذه الحالة ، ستؤدي زيادة الفاصل الزمني ping إلى تنفيذ العمل ولكن كما قلت ، التكلفة مرتفعة ، هل هناك أي حل بديل لذلك؟

الرجاء إخبارنا بمجرد إصلاح هذه المشكلة ، نفس المشكلة بالنسبة لي ، إصداري أدناه:

"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'،
خدمة العميل: صحيح ،
// أدناه هي خيارات engine.IO
بينغ الفاصل الزمني: 40000 ،
pingTimeout: 25000 ،
UpgradeTimeout: 30000 ، // القيمة الافتراضية 10000 مللي ثانية ، حاول تغييرها إلى 20 كيلو أو أكثر
الوكيل: خطأ ،
ملف تعريف الارتباط: خطأ ،
رفض غير مصرح به: خطأ ،
التأخير: 1000 ،
إعادة الاتصال تأخير الحد الأقصى: 5000
}

عميلي:

إعادة الاتصال: صحيح ،
التأخير: 1000 ،
إعادة الاتصال تأخير التأخير: 5000 ،
إعادة الاتصال المحاولات: إنفينيتي ،
// خيارات موقعنا
النقل: ["الاقتراع" ، "websocket"] ،
آمن: صحيح ،
رفض غير مصرح به: خطأ ،
ForceNew: صحيح ،
المهلة: 60000

مرحبا فايزان
يمكنك تشغيل هذا الرمز كـ -
** لقد استخدمت نفس الإصدار الذي قدمته لك ..

جانب الخادم - الرمز:

خادم const = يتطلب ('http'). createServer () ؛
const io = تتطلب ('socket.io') (الخادم ، {
// المسار: '/socket.io' ،
خدمة العميل: صحيح ،

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 ("اتصال" ، الوظيفة (المقبس) {
socket.emit ('مرحبًا'، {message: 'Welcome!'، id: socket.id})؛
socket.on ('Sunil'، console.log) ؛
}) ؛

server.listen (3000) ؛

رمز جانب العميل:

var client = يتطلب ("socket.io-client") ؛
var socket = client.connect ("http: // localhost: 3000" ، {
إعادة الاتصال: صحيح ،
التأخير: 1000 ،
إعادة الاتصال تأخير التأخير: 5000 ،
إعادة الاتصال المحاولات: إنفينيتي ،
وسائل النقل: ["websocket"] ،
آمن: خطأ ،
رفض غير مصرح به: خطأ ،
ForceNew: صحيح ،
المهلة: 6000
}) ؛

socket.connect () ؛
socket.emit ("Sunil"، {
البيانات: "مرحبًا"
}) ؛
socket.on ('مرحبًا' ، الوظيفة (البيانات) {
console.log (بيانات)
socket.emit ("Sunil"، {
البيانات: 'Faizan'،
المعرّف: data.id
}) ؛

socket.disconnect();

}) ؛

يعتبر
سونيل ياداف

في 09-May-2019 ، الساعة 4:05 مساءً ، كتب Faizan Zahid [email protected] :

إعادة الاتصال: صحيح ،
التأخير: 1000 ،
إعادة الاتصال تأخير التأخير: 5000 ،
إعادة الاتصال المحاولات: إنفينيتي ،
// خيارات موقعنا
النقل: ["الاقتراع" ، "websocket"] ،
آمن: صحيح ،
رفض غير مصرح به: خطأ ،
ForceNew: صحيح ،
المهلة: 60000

من المحتمل حل بديل من جانب العميل إذا كان أي شخص مهتمًا حتى يتم إصلاح المشكلة. سيؤدي ذلك إلى عدم تحرير المتصفح للذاكرة وقد يتسبب في استخدام الذاكرة بشكل مفرط.

  • كما هو موضح هنا ، https://apple.stackexchange.com/questions/344183/safari-12-mac-does-includeinternaldebugmenu-1-still-work ، امنح تطبيق Terminal الوصول الكامل إلى القرص محليًا وأعد تشغيل المحطة.
  • افتح نافذة طرفية ، والصق وتشغيل الأمر defaults write com.apple.Safari IncludeInternalDebugMenu 1
  • أعد تشغيل Safari. سترى قائمة تصحيح جديدة في الجزء العلوي الأيمن.
  • ضمن Debug-> Miscellaneous Flags ، قم بتمكين علامتين "Disable App Nap" و "Disable Hidden Page Timer Throttling" وأعد تشغيل Safari.

إذا كان لدى أي شخص حل Chrome البديل ، فسيكون ذلك مفيدًا

هل تستخدم Safari لمضيف webdev المحلي؟ 🤔

هل تستخدم Safari لمضيف webdev المحلي؟ 🤔

ليس حقًا ، ولكنه أمر مزعج مع عمليات قطع الاتصال المستمرة لاختبار تطبيقي. يوفر هذا حلاً مؤقتًا حتى يتم إصلاحه في 3.0. هذا ليس حلا. لقد نشرت ما إذا كان سيساعد شخصًا ما أثناء التطوير.

أنا أستخدم pingInterval و pingTimeouts منخفضة للغاية لإجراء تغييرات في حالة عدم الاتصال في الوقت الفعلي ، وضبطها على 30 ثانية من شأنه أن يكسر التدفق الخاص بي ... هل يعرف أي شخص طريقة لحل هذه المشكلة حتى أتمكن من استخدام "الإصلاح" للمهلة الطويلة للمتصفح الذي يعمل في الخلفية نوافذ التبويب؟

أي تحديثات على هذا؟

أنا أستخدم pingInterval و pingTimeouts منخفضة للغاية لإجراء تغييرات في حالة عدم الاتصال في الوقت الفعلي ، وضبطها على 30 ثانية من شأنه أن يكسر التدفق الخاص بي ... هل يعرف أي شخص طريقة لحل هذه المشكلة حتى أتمكن من استخدام "الإصلاح" للمهلة الطويلة للمتصفح الذي يعمل في الخلفية نوافذ التبويب؟

يجب أن تكون أحداث الفصل على المقبس للتعامل مع الوجود ، عندما ينفصل المقبس ، ابحث عن المستخدم وقم بتمييزه على أنه غير متصل في مخزن البيانات الخاص بك

فيما يلي الإعدادات الافتراضية من الوثائق. يبدو أنه يتم إرسال اختبار ping كل 25 ثانية وكل اختبار يستغرق 5 ثوانٍ لإكماله.

pingTimeout | 5000 | كم مللي ثانية بدون حزمة بونج للنظر في الاتصال مغلق
- | - | -
بينغ إنترفال | 25000 | كم مللي ثانية قبل إرسال حزمة بينج جديدة

لقد لاحظت هذا الخطأ نفسه ولكن في سياق مختلف ، لذلك سأقوم بكتابة سريعة لمشكلتي والحل لأي شخص آخر ينتهي به الأمر هنا.

كان السيناريو الخاص بي على Chrome لنظام Android حيث تم إسقاط الاتصال بعد قفل الشاشة.

أنا أستخدم رمزًا مميزًا لتحديد نفس المستخدم عبر اتصالات مختلفة ، والتي أرسلها من العميل عند الاتصال باستخدام نهج خيار الاستعلام وأقوم بتحديث الرمز المميز برمز جديد تم استلامه من الخادم:

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

تكمن المشكلة في أن عميل Chrome لنظام Android سيرسل إلى الخادم رمزًا مميزًا لسلسلة فارغة عند إعادة الاتصال. وهو ما لا أتوقعه منذ أن أضفت المستمع 'reconnect_attempt' والذي يتأكد من تعيين أحدث رمز من localStorage .

حسنًا ، بعد بضع ساعات من التصحيح باستخدام تسجيل وحدة التحكم لجميع أحداث العميل المحتملة ، أدركت أن حدث '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 هو متغير مثيل يتم استخدامه عند الاتصال وجميع عمليات إعادة الاتصال اللاحقة ، لذلك يمكنني تحديثه بمجرد أن أرغب في ذلك. لست مضطرًا إلى انتظار أي حدث متعلق بإعادة الاتصال.

أشعر ببعض التضليل من خلال مستندات خيارات الاستعلام . ربما أسأت فهم حالة الاستخدام في هذا المثال؟ ولكن إذا كانت مشابهة لحالة الاستخدام الخاصة بي ، فبدلاً من المثال 'reconnect_attempt' ، يمكن أن توضح المستندات أن io.opts.query هو متغير مثيل يمكن تغييره واستخدام قيمته الحالية في جميع عمليات إعادة الاتصال اللاحقة. لذلك يمكن تغييره متى أردت تحديث الرمز المميز ، حتى في حدث مخصص 'refresh_token' على سبيل المثال. يمكنني إجراء العلاقات العامة إذا كنت تعتقد أنها فكرة جيدة لتحسين المستندات.

يحرر:
بعد إجراء مزيد من التحقيق ، أدركت أن خطئي كان أن المستمع 'reconnect_attempt' تمت إزالته من جزء آخر من الكود الخاص بي ...: man_facepalming: لهذا السبب لم أكن أراه في التسجيل الخاص بي. إذن ، نعم ، تسلسل الأحداث لسيناريو إعادة الاتصال الخاص بي هو في الواقع:

  • قطع الاتصال (السبب: "إغلاق النقل")
  • إعادة الاتصال (محاولة: 1)
  • إعادة الاتصال (محاولة: 1)
  • إعادة الاتصال
  • يبدأ ping / pong مرة أخرى

ومع ذلك ، فإن إدراكي أنه يمكن تغيير io.opts.query وقتما تشاء لا يزال ساريًا. : sweat_smile:

هل لا يزال من المقبول الرجوع إلى إصدار سابق؟ أقوم بتشغيل 2.0.3 ولكن لا يبدو أنه يعمل.

مرحبًا ، أواجه نفس النوع من المشكلات ولكن مع وجود خطأين. حاولت حل omardoma . هل أستطيع مساعدتك؟
نظام التشغيل - 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");

أنا أستخدم الإصدار 2.3.0 من socket.io. أنا استخدم اتصال websocket للعميل. عندما يكون لدى عميلي تنبيه متصفح (متزامن) في واجهة المستخدم وإذا لم يرفض المستخدم التنبيه لأكثر من 30 ثانية (pingTimeout + pingInterval) ، أرى رسالة "Websocket في حالة الإغلاق أو الإغلاق بالفعل" وأحصل على رسالة قطع الاتصال بسبب pingTimeout. لا أريد قطع الاتصال بمقبس الويب هذا عندما يكون لدى واجهة المستخدم تنبيه. إذا قمت بزيادة pingTimeout إلى 10 دقائق ، فلن يحدث قطع الاتصال لمدة 10 دقائق. ولكن مما قرأته في التعليقات أعلاه ، قد يكون لهذا تأثير سلبي (قد لا يعرف العميل أن هناك انقطاعًا حتى 10 دقائق). لكنني لاحظت أنه في حالة حدوث انقطاع في الشبكة وما إلى ذلك ، فإننا نحصل على قطع الاتصال بسبب قريب من النقل. إذن هل من المقبول زيادة pingTimeout + pingInterval؟ هل هناك سيناريو محدد عندما لا يتم اكتشاف انقطاع الاتصال؟ أم أن هناك طريقة أخرى لإصلاح هذا؟

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات