2011-12-05 11 views
24

दो संबंधित प्रश्नों है कि और अधिक के ज्ञान की मेरी कमी में निहित किया जा सकता है के लिए बाध्य करने के OnOpen करता है कैसे/ब्राउज़रों पूर्व पार्स यदि जावास्क्रिप्ट:जावास्क्रिप्ट WebSockets - को नियंत्रित प्रारंभिक कनेक्शन/जब

var ws = new WebSocket("ws://ws.my.url.com"); 
ws.onOpen = function() { ... }; 

कोई प्रतीत होता है WebSocket के प्रारंभिककरण को सीधे कॉलबैक में लपेटने से पहले, तो मुझे लगता है कि जैसे ही जावास्क्रिप्ट कोड लोड हो जाता है और कन्स्ट्रक्टर तक पहुंच जाता है, कनेक्शन कनेक्शन बनाया जाता है?

onOpen संपत्ति ws से जुड़ी हुई है? क्या दौड़ की स्थिति की कोई संभावना है (यदि किसी कारण से आपके पास सॉकेट की परिभाषा और onOpen की परिभाषा के बीच कुछ कोड था?) ताकि onOpen कनेक्शन स्थापित होने से पहले/बाद में अनिश्चित रूप से बाध्य हो (मुझे पता है कि आप वैकल्पिक रूप से वैकल्पिक रूप से ws.readyState देखें)। इसके लिए पूरक, वेबसाकेट हैंडशेक अवरुद्ध है?

मुझे एहसास है कि इस समय यह एक मसौदा है, संभवतः कार्यान्वयन निर्भर है और शायद मुझे कुछ स्पष्ट रूप से स्पष्ट याद आ गया हो, लेकिन मैं अपने इंटरनेट खोजों/ड्राफ्ट डब्ल्यू 3 सी स्पेक के माध्यम से स्कीम के बारे में विशेष कुछ भी नहीं देख पा रहा था, इसलिए कोई मदद websockets/जावास्क्रिप्ट की आंतरिक कार्यप्रणाली की मेरी समझ में बहुत सराहना की है!

उत्तर

25

जावास्क्रिप्ट एकल थ्रेडेड है जिसका अर्थ है कि निष्पादन के मौजूदा दायरे को पूरा होने तक नेटवर्क कनेक्शन स्थापित नहीं किया जा सकता है और नेटवर्क निष्पादन को चलाने का मौका मिलता है। निष्पादन का दायरा वर्तमान कार्य हो सकता है (नीचे दिए गए उदाहरण में connect फ़ंक्शन)। इसलिए, आप onopen ईवेंट को याद कर सकते हैं यदि आप सेटटाइमआउट का उपयोग करने में बहुत देर से बाध्य करते हैं उदा। इस उदाहरण में आप घटना याद आती है कर सकते हैं:

दृश्य: http://jsbin.com/ulihup/edit#javascript,html,live

कोड:

var ws = null; 

function connect() { 
    ws = new WebSocket('ws://ws.pusherapp.com:80/app/a42751cdeb5eb77a6889?client=js&version=1.10'); 
    setTimeout(bindEvents, 1000); 
    setReadyState(); 
} 

function bindEvents() { 
    ws.onopen = function() { 
    log('onopen called'); 
    setReadyState(); 
    }; 
} 

function setReadyState() { 
    log('ws.readyState: ' + ws.readyState); 
} 

function log(msg) { 
    if(document.body) { 
    var text = document.createTextNode(msg); 
    document.body.appendChild(text); 
    } 
} 

connect(); 

आप उदाहरण आप अच्छी तरह से देख सकते हैं कि 'OnOpen तथाकथित' लॉग लाइन उत्पादन कभी नहीं है चलाते हैं। ऐसा इसलिए है क्योंकि हमने घटना को याद किया था।

हालांकि, यदि आप new WebSocket(...) रखते हैं और onopen ईवेंट को बाध्यकारी निष्पादन के समान दायरे में रखते हैं तो कोई मौका नहीं है कि आप ईवेंट को याद करेंगे।

scope of execution पर अधिक जानकारी के लिए और इन पंक्तियों को निर्धारित, निर्धारित और संसाधित करने के लिए जॉन रेसिग की पोस्ट Timers in JavaScript पर एक नज़र डालें।

+0

सीटीआर घटना का आह्वान कर सकता है ... क्या यह दस्तावेज नहीं हुआ है? – usr

+1

@usr एपीआई [spec राज्य] (http://dev.w3.org/html5/websockets/#handler-websocket-onopen) कि "ऑनसोपेन" ईवेंट ट्रिगर किया जाना चाहिए जब "वेबस्केट कनेक्शन स्थापित हो"। मेरे उत्तर के पहले पैरा के अनुसार, यह केवल निष्पादन के दायरे को पूरा करने के बाद ही हो सकता है (कोड जो कन्स्ट्रक्टर को बुलाता है)। अगर डेवलपर को 'ओपन' घटना से जुड़ने का मौका मिलने से पहले 'ओपन' को ट्रिगर किया जा सकता है तो यह एक मौलिक दोष होगा। – leggetter

+0

** फेसपाल्म ** गंभीरता से ?? ** श्वास ** आपको संदेह नहीं है, बस फर्श लगाया गया है कि यह इस तरह से किया गया था। पृथ्वी पर क्यों उन्होंने कॉन्फ़िगरेशन ऑब्जेक्ट प्रदान नहीं किया है जैसे लगभग हर जावास्क्रिप्ट लाइब्रेरी ऑब्जेक्ट सृजन के लिए करता है ... – Gus

1

आपकी स्क्रिप्ट निष्पादित होने के बाद तक कोई वास्तविक I/O नहीं होगा, इसलिए दौड़ की स्थिति नहीं होनी चाहिए।

+0

बंद करने के लिए तो कोड सेट 'ws' जबकि यह लोड हो रहा है है , 'ओपन' सेट अप करता है और पूरे जेएस फ़ाइल को लोड करने के बाद कनेक्शन निष्पादित करता है? क्या होगा यदि कोड किसी फ़ंक्शन में लपेटा गया था ताकि स्क्रिप्ट लोड होने के बाद मैं फ्लाई पर एकाधिक सॉकेट कनेक्शन बना सकूं, उदाहरण के लिए। फ़ंक्शन (i) {ws = new webSocket ("ws: //url.com/" + i); ws.onOpen (...);} ऐसा लगता है कि घोषणा आदेश सिंक से बाहर है प्रारंभिक आदेश। – dbeacham

2

@leggetter सही है, निम्नलिखित कोड था कार्यान्वित क्रमिक रूप से:

(function(){ 
    ws = new WebSocket("ws://echo.websocket.org"); 
    ws.addEventListener('open', function(e){ 
     console.log('open', e); 
     ws.send('test'); 
    }); 
    ws.addEventListener('message', function(e){console.log('msg', e)}); 

})(); 

लेकिन, W3C spec में वहाँ एक जिज्ञासु लाइन है:

वापसी एक नया WebSocket वस्तु, और इन चरणों को जारी रखने के लिए पृष्ठभूमि (स्क्रिप्ट को अवरुद्ध किए बिना)।

यह मेरे लिए भ्रमित था, जब मैं इसके लिए ब्राउज़र एपीआई सीख रहा था। मुझे लगता है कि उपयोगकर्ता एजेंट इसे अनदेखा कर रहे हैं, या मैं इसे गलत व्याख्या कर रहा हूं।

2

इस तथ्य पर ध्यान दें कि I/O निष्पादन के दायरे में हो सकता है। उदाहरण के लिए, निम्न कोड

var ws = new WebSocket("ws://localhost:8080/WebSockets/example"); 
alert("Hi"); 
ws.onopen = function(){ 
    writeToScreen("Web Socket is connected!!" + "<br>"); 
}; 
function writeToScreen(message) { 
    var div = document.getElementById('test'); 
    div.insertAdjacentHTML('beforeend', message); 
} 

में, संदेश "Web Socket is connected" दिखाई देते हैं या नहीं होगा, निर्भर करता है कि कितना समय ले लिया आप "Hi" चेतावनी

+0

मैंने क्रोम v53 में यह कोशिश की और इससे कोई फर्क नहीं पड़ता कि मुझे चेतावनी बंद करने में कितना समय लगता है, मैं कभी भी 'ओपन' घटना को याद नहीं करता हूं। क्या आपने इसका परीक्षण किया? क्या ब्राउज़र से ब्राउजर से अलग है? –

संबंधित मुद्दे