WebSocketサーバーに対してhtml5+jQueryのWebクライアントをつくってみたところエラーが発生しました。
仕方ないのでエラーを捕捉しようとしますが、なぜかどうやってもUncaughtだよ!とコンソールに怒られます。
ということで、 非同期処理時のtry~catchについてのメモです。
#WebSocketは非同期通信
こちらがとても詳しいです。
参考: WebSocketについて調べてみた。
で、WebSocketを扱うときは基本的に接続時にsetTimeout
で非同期化してあげることになります。
とりあえず、サーバーと接続が確立したら挨拶を投げてあげるクライアントをつくってみました。
// 呼び出すhtmlでjQueryを先に読み込んでおく
var ws = new WebSocket("ws://192.168.0.x:80"); //接続
ws.onopen = wsOnOpen; //接続できたとき
ws.onerror = wsOnError; //接続エラーのとき
ws.onclose = wsOnClose; //接続を閉じたとき
function wsOnOpen() {
//接続できたときの処理..
try {
setTimeout(function(){ws.send("Hey!")}, 1000); //へい!
} catch (e) {
console.log(e);
wsOnError();
}
}
function wsOnError() {
//接続エラーのときの処理..
}
function wsOnClose() {
//接続を閉じたときの処理..
}
...
..
WebSocketのsendメソッドを即時関数で囲ってあげてsetTimeOut
の引数とします。これが常套みたいですね。
さらになにかあると怖いので、とりあえずsetTimeOut
をtry
の中にいれておきました。
#エラーイベント(onerror)
参考: いまさらHTML5 (WebSocket編)
ws.onerror = wsOnError
としておくことで、エラー発生時にはfunction wsOnError()
がいろいろと処理をしてくれます。
ここでは、接続先が間違っていたときにはうまくこの処理に移行してくれました。
#onerrorが効かないとき
スクリプトを実行してみると、接続先があっていれば最初はうまくつながってくれます。
しかし、ちゃんと接続終了処理をせずに同じサーバーに再接続したりするとUncaught Error: InvalidStateError..
が発生していたりします。しかも発生した行はsetTimeOut
のところ。
めっちゃtry
しとるやろ!なんでや!
#非同期処理をさせる関数のなかでtry
非同期処理をさせる関数の外でtry
を張ると、処理が返ってきたころにはとっくにtry
は終わってしまっているのでした。よって、エラーが出ても捕まえることはできません。
ということは try~catchを関数内に書くとなんとかなりそうです。
// 呼び出すhtmlでjQueryを先に読み込んでおく
var ws = new WebSocket("ws://192.168.0.x:80"); //接続
ws.onopen = wsOnOpen; //接続できたとき
ws.onerror = wsOnError; //接続エラーのとき
ws.onclose = wsOnClose; //接続を閉じたとき
function wsOnOpen() {
//接続できたときの処理..
setTimeout(function(){
try {
ws.send("Hey!") //へい!
} catch (e) {
console.log(e);
wsOnError();
}
}, 1000);
}
function wsOnError() {
//接続エラーのときの処理..
}
function wsOnClose() {
//接続を閉じたときの処理..
}
...
..
ただしこれですっきり解決というわけではなく、
このようなエラーが出たときはソケットがちゃんと準備できてなかったりとかいう別の原因が大きいと思われるので、WebSocketのメソッド周りでの適切な対処もしくはcatch内での処理が重要です。
WebSocketでなくても非同期処理時のデバッグとして多少は使えるかもしれません。