سؤال

في تطبيق Mochiweb الخاص بي ، أستخدم طلب HTTP طويلًا. أردت اكتشاف متى توفي الاتصال مع المستخدم ، واكتشفت كيفية القيام بذلك عن طريق القيام:

Socket = Req:get(socket),
inet:setopts(Socket, [{active, once}]),
receive
     {tcp_closed, Socket} ->
             % handle clean up
     Data ->
             % do something 
end.

هذا يعمل عندما: يقوم المستخدم بإغلاق علامة التبويب/متصفحه أو يقوم بتحديث الصفحة. ومع ذلك ، عندما يموت اتصال الإنترنت فجأة (قل إشارة wifi فقدت فجأة) ، أو عندما يتعطل المتصفح بشكل غير طبيعي ، لا أستطيع اكتشاف إغلاق TCP.

هل أفتقد شيئًا ، أم أن هناك أي طريقة أخرى لتحقيق ذلك؟

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

المحلول

هناك بروتوكول Keepalive TCP ويمكن تمكينه inet:setopts/2 تحت الخيار {keepalive, Boolean}.

أود أن أقترح أنك لا تستخدمه. تميل مهلة الاحتفاظ بالحيوية و Retries إلى أن تكون نظامًا واسعًا ، وهي اختيارية بعد كل شيء. يعد استخدام المهلة على مستوى البروتوكول أفضل.

بروتوكول HTTP لديه مهلة طلب رمز الحالة الذي يمكنك إرساله إلى العميل إذا كان يبدو ميتًا.

تفحص ال after بند في كتل الاستقبال التي يمكنك استخدامها في مهلة في انتظار البيانات ، أو استخدام وحدة المؤقت ، أو الاستخدام erlang:start_timer/3. لديهم جميعًا خصائص أداء مختلفة وتكاليف الموارد.

نصائح أخرى

لا يوجد افتراضي "Keep Away" (ولكن يمكن أن يكون تمكين إذا مدعومة) بروتوكول على TCP: في حالة وجود خطأ في الاتصال عند عدم تبادل أي بيانات ، فإن هذا يترجم إلى "فشل صامت". ستحتاج إلى حساب هذا النوع من الفشل بنفسك على سبيل المثال تنفيذ شكل من أشكال التحقيق في الاتصال.

كيف يؤثر هذا على HTTP؟ HTTP هو بروتوكول عديمي الجنسية - وهذا يعني أن كل طلب مستقل عن أي شيء آخر. لا تتغير وظيفة "Keep Alive" لـ HTTP التي لا يزال من الممكن حدوثها "الفشل الصامت".

فقط عند تبادل البيانات هل يمكن اكتشاف هذا الشرط (أو عندما يتم تمكين TCP على قيد الحياة).

أود أن أقترح إرسال مستوى التطبيق الاحتفاظ بالرسائل عبر ترميز HTTP. اجعل العميل/الخادم ذكيًا بما يكفي لفهم رسائل Keep Alive وتجاهلها إذا وصلوا في الوقت المحدد أو يغلقون وإعادة تأسيس الاتصال مرة أخرى.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top