سؤال

لقد تابعت Tomek Janczuk عينة Pub/Sub باستخدام قناة WCF Duplex Bolling HTTP لكنني لاحظت أنه عندما يفصل العميل عن طريق إغلاق المتصفح ، لا يلاحظ الخدمة في رد الاتصال التالي. كنت أتوقع استثناءًا أو شيءًا ليقول إن نقطة النهاية لم تعد هناك.

كيف يمكنك أن تعرف متى يختفي العميل ، وذلك للتوقف عن النشر على هذا العميل؟

هل كانت مفيدة؟

المحلول

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

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

نصائح أخرى

لمعرفة بالتأكيد: غير ممكن.

عند إغلاق اتصال TCP (كامن مكالمة HTTP) ، يتم إرسال رسالة TCP خاصة إلى الخادم - حزمة الزعانف. على الرغم من أن HTTP عديمي الجنسية ، إلا أن اتصال TCP الأساسي هو أمر مناسب ومع الحفاظ على اتصال TCP الأساسي ، عادة ما يظل مفتوحًا. إذا تم التخلص من العميل ، يتم إغلاق اتصال TCP وعادة ما يتم إرسال رسالة إلى الخادم. ولكن إذا تعطلت أو تم فصل شبكتها ، فلن يكون لها الوقت الكافي للقيام بذلك. لذلك في كلمة واحدة ، لا يمكنك أن تكون متأكدا.

هنا لمزيد من المعلومات.

من الصعب ، شبه مستحيل (سبب قدرات SL Duplex المحدودة). لقد قمنا بتطبيق قائمة من المستخدمين في خدمتنا ، وقمنا بإضافة خاصية "isDisconnected" و LastCommunicationTime ، بمجرد أن تحصل خدمة WCF على مهلة عندما تحاول إضافة رسالة في Quare-Queue الصادرة ، وتفشل ، وترمي استثناء مهلة. نضع علامة "ISDISCONNECTE = TRUE" وفي المرة القادمة لا تحاول إرسال الرسالة إلى هذا المستخدم.

يستمر مؤشر ترابط آخر في النظر إلى ذلك ، وإذا لاحظ أنه تم تجاوز وقت التواصل الأخير بقيمة الوقت و isDisconnected = صحيح ، فإنه يزيل المستخدم من القائمة ، ما لم يحاول المستخدم نفسه الاتصال مرة أخرى خلال هذه الفترة الزمنية (التي نقوم بها تحديد من قبل المستخدم الخاص به).

هناك الكثير من الأشياء التي فعلناها يدويًا للتعامل مع هذه المشكلة لأنها كانت تجعل خدمة WCF مشغولة كثيرًا.

لقد واجهت هذه المشكلة وأنشأت موضوعًا يزيل العملاء غير المتصل بالرمز التالي. إنه يعمل بشكل جيد ولكنه يسقط العميل غير المتصل من قائمة العميل بعد 10-15 دقيقة (وهو ما كان على ما يرام بالنسبة لي).

    new Thread(new ThreadStart(() =>
    {
        while (SilverlightClients != null)
        {
                lock (SilverlightClients)
                {
                    SilverlightClients = SilverlightClients.Where(d => (d.Callback as IContextChannel).State != CommunicationState.Opened).ToList();
                }

            Thread.Sleep(1000);
        }
    })) { Name = "Thread Remove Disconnected Clients" }.Start();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top