2つの関連する質問は、ブラウザがJavaScriptを事前に解析する方法/場合に関する私の知識の欠如に根ざしている可能性があります。
var ws = new WebSocket("ws://ws.my.url.com");
ws.onOpen = function() { ... };
WebSocket
の初期化を直接制御する方法はないようです。コールバックでラップする以外に、JavaScriptコードが読み込まれてコンストラクターに到達するとすぐに接続が作成されると思いますか?
onOpen
プロパティはいつws
にアタッチされますか?競合状態が発生する可能性はありますか(何らかの理由でソケットの定義とonOpen
の定義の間にコードがあった場合)、onOpen
が予測不能に前/後にバインドされます。接続が確立されました(オプションでws.readyState
)。これを補足すると、WebSocketハンドシェイクはブロックされますか?
現時点ではドラフトであり、実装に依存している可能性があり、目立たないように見逃している可能性がありますが、w3c仕様のドラフトでインターネット検索/スキムに特に関連するものは見当たらないので、私の理解に役立つwebsockets/javascriptの内部の仕組みは非常に高く評価されています!
JavaScriptはシングルスレッドです。つまり、現在の実行スコープが完了し、ネットワークの実行が実行されるまで、ネットワーク接続を確立できません。実行範囲は、現在の関数(以下の例ではconnect
関数)にすることができます。したがって、setTimeoutを使用して非常に遅くにバインドすると、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 called」ログ行が出力されないことがよくわかります。これは、イベントに参加できなかったためです。
ただし、new WebSocket(...)
とonopen
イベントへのバインディングを同じ実行範囲に維持すると、イベントを見逃すことはありません。
_scope of execution
_の詳細と、これらがどのようにキューに入れられ、スケジュールされ、処理されるかについては、John Resigの JavaScriptのタイマー に関する投稿をご覧ください。
実行範囲内で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"
アラート
@ 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オブジェクトを返し、これらの手順を(スクリプトをブロックせずに)バックグラウンドで続行します。
私がブラウザAPIを学んでいたとき、それは私を混乱させました。私はユーザーエージェントがそれを無視していると思います、または私はそれを誤って解釈しています。
スクリプトの実行が完了するまで実際のI/Oは発生しないため、競合状態は発生しません。