ওয়েবসকেট সঠিকভাবে বন্ধ করা হচ্ছে (এইচটিএমএল 5, জাভাস্ক্রিপ্ট)


127

আমি এইচটিএমএল 5 ওয়েবসকেট নিয়ে খেলছি। আমি ভাবছিলাম, কীভাবে আমি সংযোগটি করুণভাবে বন্ধ করব? পছন্দ করুন, যদি ব্যবহারকারী পৃষ্ঠাটি সতেজ করে বা ব্রাউজারটি বন্ধ করে দেয় তবে কী ঘটে?

একটি অদ্ভুত আচরণ রয়েছে যখন কোনও ব্যবহারকারী কেবল কল না করেই পৃষ্ঠাটি রিফ্রেশ করে websocket.close()- যখন তারা রিফ্রেশের পরে ফিরে আসে তখন এটি websocket.oncloseইভেন্টটিতে আসবে ।

উত্তর:


110

প্রোটোকল স্পেক ভি 76 অনুসারে (এটি হ'ল সংস্করণ যা বর্তমান সমর্থন সহ ব্রাউজারটি প্রয়োগ করে):

সংযোগটি পরিষ্কারভাবে বন্ধ করতে, একটি পিয়ার থেকে কেবল 0xFF বাইট সমন্বিত একটি ফ্রেম একটি পিয়ার থেকে প্রেরণ করা হয় যাতে অন্য পিয়ারটি সংযোগটি বন্ধ করে দেয় তা জিজ্ঞাসা করে।

আপনি যদি কোনও সার্ভার লিখতে থাকেন তবে সার্ভারটি ক্লায়েন্ট সংযোগ বন্ধ করার সময় আপনার কাছাকাছি ফ্রেম প্রেরণ নিশ্চিত করা উচিত। সাধারণ টিসিপি সকেট ঘনিষ্ঠ পদ্ধতিটি কখনও কখনও ধীর হয়ে যায় এবং অ্যাপ্লিকেশনগুলিকে মনে করতে পারে যে সংযোগটি এটি না থাকলেও এখনও খোলা রয়েছে।

আপনি পৃষ্ঠাটি বন্ধ বা পুনরায় লোড করার সময় ব্রাউজারটি সত্যই আপনার জন্য এটি করা উচিত। তবে আপনি পূর্ববর্তী লোড ইভেন্ট ক্যাপচার করে একটি নিবিড় ফ্রেম পাঠানো হয়েছে তা নিশ্চিত করতে পারেন:

window.onbeforeunload = function() {
    websocket.onclose = function () {}; // disable onclose handler first
    websocket.close();
};

পৃষ্ঠাটি রিফ্রেশ হওয়ার পরে কীভাবে আপনি একটি অনক্লোজ ইভেন্ট পেতে পারবেন তা আমি নিশ্চিত নই। পৃষ্ঠাটি পুনরায় লোড হয়ে গেলে ওয়েবসকেট অবজেক্ট (অনক্লোজ হ্যান্ডলার সহ) আর উপস্থিত থাকবে না। পৃষ্ঠাটি লোড হওয়ার সাথে সাথে আপনি যদি তত্ক্ষণাত্ আপনার পৃষ্ঠায় একটি ওয়েবস্কিট সংযোগ স্থাপনের চেষ্টা করছেন, তবে আপনি সম্ভবত এমন একটি সমস্যায় পড়ছেন যেখানে পুরানোটি সংযোগ বিচ্ছিন্ন হওয়ার পরে সার্ভার একটি নতুন সংযোগ অস্বীকার করছে (বা ব্রাউজার প্রস্তুত নয় আপনি যে সংযোগের চেষ্টা করছেন সেই স্থানে সংযোগ তৈরি করতে) এবং আপনি নতুন ওয়েবসকেট অবজেক্টের জন্য একটি অনক্লোজ ইভেন্ট পাচ্ছেন।


2
এটি সম্ভব যে ফায়ারফক্সে এই সংযোগটি পরবর্তী পৃষ্ঠার লোডের মধ্যেই আটকে আছে বলে মনে হচ্ছে। আমি রেফারেন্সটি খুঁজে পাচ্ছি না তবে আমি মনে করি এটি সম্পর্কে কোনও ত্রুটি থাকতে পারে। অন্য সম্ভাবনাটি হ'ল oncloseইভেন্টটি অপ্রত্যাশিতভাবে ট্রিগার করা হয়েছে, বা সম্ভবত উদ্দেশ্য নেভিগেশন, ব্যবহারকারী নেভিগেট / পৃষ্ঠাটি পুনরায় লোড হওয়ার সাথে সাথে। প্রত্যাশিত আচরণটি কী হওয়া উচিত, কোন ব্রাউজারটির এটি সঠিক এবং আমরা কীভাবে স্বয়ংক্রিয় পুনঃসংযোগ কার্যকর করব তা জিজ্ঞাসা করে আমি একটি প্রশ্ন পোস্ট করেছি ।
লেজেটার

4
ইভেন্ট সহ এই সমস্যাগুলি বিবেচনা করুনonbeforeunload
আর্টকোনিগ


35

এটির বিষয়টি হ'ল আজ ব্যবহৃত ওয়েবসকেটগুলির 2 প্রধান প্রোটোকল সংস্করণ রয়েছে। পুরানো সংস্করণ যা [0x00][message][0xFF]প্রোটোকল ব্যবহার করে এবং তারপরে হায়বি ফর্ম্যাট প্যাকেটগুলি ব্যবহার করে নতুন সংস্করণ রয়েছে ।

পুরানো প্রোটোকল সংস্করণ অপেরা এবং আইপড / আইপ্যাড / আইফোন ব্যবহার করে তাই ওয়েবসকেট সার্ভারগুলিতে পশ্চাদপদ সামঞ্জস্যতা বাস্তবায়িত করা সত্যিই গুরুত্বপূর্ণ। পুরানো প্রোটোকল ব্যবহার করে এই ব্রাউজারগুলির সাহায্যে আমি আবিষ্কার করেছি যে পৃষ্ঠাটি রিফ্রেশ করছে, বা পৃষ্ঠাটি থেকে সরে গিয়ে, বা ব্রাউজারটি বন্ধ করে দেওয়ার ফলে ব্রাউজারটি স্বয়ংক্রিয়ভাবে সংযোগটি বন্ধ করে দেবে। গ্রেট !!

তবে ব্রাউজারগুলি নতুন প্রোটোকল সংস্করণ (যেমন ফায়ারফক্স, ক্রোম এবং শেষ পর্যন্ত আই 10) ব্যবহার করে ব্রাউজারটি বন্ধ করার ফলে ব্রাউজারটি স্বয়ংক্রিয়ভাবে সংযোগ বন্ধ হয়ে যাবে। এর অর্থ হ'ল, আপনি যদি পৃষ্ঠাটি রিফ্রেশ করেন, বা পৃষ্ঠাটি সরিয়ে নিয়ে যান, ব্রাউজারটি স্বয়ংক্রিয়ভাবে সংযোগটি বন্ধ করে না। যাইহোক, ব্রাউজারটি যা করে তা হ'ল প্রথম বাইট (প্রোটো আইডেন্টিটি) থাকার কারণে একটি হাইবি প্যাকেট সার্ভারে প্রেরণ করা (নিকটস্থ 0x88ডেটা ফ্রেম হিসাবে বেশি পরিচিত)। সার্ভারটি একবার এই প্যাকেটটি গ্রহণ করলে এটি জোর করে সংযোগটি নিজেই বন্ধ করতে পারে, যদি আপনি এটি চয়ন করেন।


4
সার্ভারের একটি ব্যবহারিক উদাহরণ কীভাবে এই হাইবি প্যাকেট পরিচালনা করবেন?
albanx

9
উন্মাদ বলে মনে হচ্ছে এটি সংযোগটি বন্ধ করে দেয় না। ওয়েবসকেট ভেরিয়েবল পৃষ্ঠা পুনঃলোডে মুছে ফেলা হয়েছে, সুতরাং যদি সংযোগটি অ্যাক্সেস না করা যায় তবে কেন খোলা থাকবে? সংযোগটি পুনঃব্যবহার করা অর্থহীন হবে না।
ট্রায়ঙ্কো

@ আলবানেক্স নীচে আমার উত্তরটি দেখুন
আর্টকোনিগ

ওয়েবসকেট ক্লায়েন্ট (যেমন ব্রাউজার) থেকে কীভাবে বন্ধ ফ্রেম প্রেরণ করা যায় তার কোনও কোড নমুনা। আমি ws এনএমপি মডিউলটি ব্যবহার করছি
শাইক সৈয়দ আলী

3

থুব দ্বারা উল্লিখিত হিসাবে , কিছু ব্রাউজার স্বয়ংক্রিয়ভাবে ওয়েবসকেটগুলি বন্ধ করে না। কোনও ক্লোজার-পাশের "ব্রাউজার উইন্ডো বন্ধ" ইভেন্টগুলি হ্যান্ডেল করার চেষ্টা করবেন না। বর্তমানে এটি করার কোনও নির্ভরযোগ্য উপায় নেই, যদি আপনি প্রধান ডেস্কটপ এবং মোবাইল ব্রাউজারগুলির সমর্থন বিবেচনা করেন (যেমন onbeforeunloadমোবাইল সাফারিটিতে কাজ করবে না)। এই সমস্যাটি সার্ভার-সাইডটি পরিচালনা করার জন্য আমার ভাল অভিজ্ঞতা ছিল। উদাহরণস্বরূপ আপনি জাভা ইই ব্যবহার করেন, জাভ্যাক্স.ইউবসকেট.এন্ডপয়েন্টটি দেখুন , আপনি ব্রাউজার উইন্ডোটি বন্ধ / পুনরায় লোড করলে OnCloseপদ্ধতি বা OnErrorপদ্ধতিটি বলা হবে either


1
আমার ক্ষেত্রে, ডেটা স্থানান্তর করার সময় সংযোগ বন্ধ হয়ে যাচ্ছে, এটি অপেরা এবং আইওএস পরিবার ব্রাউজারগুলির ক্ষেত্রে ভাল কাজ করে। দয়া করে আমাকে সাহায্য করুন .. আমি গত দুই সপ্তাহ থেকে এই সমস্যাটির সাথে লড়াই করছি। stackoverflow.com/q/30799814/2225439
Mrug

2

ওয়েব সকেটের ঘনিষ্ঠ পদ্ধতি ব্যবহার করে যেখানে আপনি প্রয়োজন অনুযায়ী যে কোনও ফাংশন লিখতে পারেন।

var connection = new WebSocket('ws://127.0.0.1:1337');
    connection.onclose = () => {
            console.log('Web Socket Connection Closed');
        };
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.