今回は、
WebSocketオブジェクト
ブラウザのJavaScriptからWebSocketを利用するために、
インスタンス化
WebSocketはインスタンス時、
new WebSocket(url)
new WebSocket(url,protocol)
イベント登録
WebSocketは以下の4つのイベントハンドラが定義されています。
onopen | WebSocketの接続が完了した時に呼ばれます |
onclose | WebSocketが切断された時に呼ばれます |
onmessage | 接続先からメッセージを受け取った時に呼ばれます |
onerror | エラー発生した時に呼ばれます |
メソッド
定義されているWebSocketのメソッドは以下の2つです。
send(message) | messageを接続先に送信します |
close() | WebSocketの接続を切断します。意図的に切断する時だけでなく、 |
ステータス
WebSocketの接続状態を調べる事ができます。値こそ違いますが、
readyState | 接続のステータスです。0~2の値をとります。読み取り専用です |
WebSocketクラスに定数が準備されています。ステータスを確認する際には必ず定数を使うようにしてください。
CONNECTING | 接続開始の処理中を示す定数です |
OPEN | 接続済を示す定数です |
CLOSED | 切断済を表す定数です |
その他のプロパティ
その他に以下のプロパティがあります。
URL | 接続先を示すプロパティです。読み取り専用です |
bufferedAmount | sendメソッドによって送信が指定されてデータは、 |
サブプロトコル
サブプロトコルは、
Jettyでは、
protected WebSocket doWebSocketConnect(HttpServletRequest request,
String protocol) {
if(protocol=="file"){
return new FileWebSocket();
}else{
return new ChatWebSocket();
}
}
今の仕様では、
最新ドラフト
最新のドラフトでは以下のように修正されています。
サブプロトコルの複数指定
コンストラクタがひとつ増えました。第二引数のprotocolsは文字列の配列です。複数のサブプロトコルを複数指定できます。WebSocketプロトコルの仕様にはまだ反映されていないようですが、
new WebSocket(url,protocols)
ステータス
WebSocketの接続状態を示すreadStateの仕様が変更になりました。
readyState | 接続のステータスの範囲が0~3に変更されました。読み取り専用です |
定数に
CONNECTING | 接続開始の処理中を示す定数です |
OPEN | 接続済を示す定数です |
CLOSING | 切断中を表す定数です |
CLOSED | 切断済を表す定数です |
プロパティ
protocol | サブプロトコル名を返します。インスタンス化の際に、 |
url | 接続先を示すプロパティが小文字に変更になりました。読み取り専用です |
クライアント側の実装
それでは、
index.html
チャットアプリケーションのHTMLファイルです。後述する
<html>
<head>
<title>WebSocketChat</title>
<link type="text/css" href="common.css" rel="stylesheet">
<script src="common.js" type="text/javascript"></script>
</head>
<body>
<div><input type="text" id="message" /><input type="button" id="send" value="send" /></div>
<div id="messages"></div>
</body>
</html>
common.css
チャットアプリケーションの見た目を整えるスタイルシートです。最低限の指定しか行なっていないため、
#message{
width:400px;
}
#messages{
width:100%;
height:400px;
overflow:hidden;
border:0px none transparent;
}
common.js
今回の肝となるJavaScriptのコードです
//グローバル変数にWebSocketの変数を定義
var ws;
//getElementByIdの別名を定義
function $(id){
return document.getElementById(id);
}
//WebSocketが接続された時に、「send」ボタンが有効になる
function onOpenWebSocket(){
$("send").addEventListener("click",sendMessage,false);
dispMessage("connected");
}
//WebSocketが切断された時に、「send」ボタンを無効にする
function onCloseWebSocket(){
$("send").removeEventListener("click",sendMessage,false);
dispMessage("disconnected");
}
//接続先よりメッセージを受信した時に、空文字でなければ画面に表示する
function onMessageWebSocket(event){
var msg=event.data;
if(msg==""){return;}
dispMessage("> "+msg);
}
//ウィンドウを閉じたり画面遷移した時にWebSokcetを切断する
function onUnload(){
ws.close();
}
//画面にメッセージを表示する
//上に表示されるメッセージが最新となる
function dispMessage(msg){
var elem=document.createElement("div");
elem.appendChild(document.createTextNode(msg));
if($("messages").hasChildNodes()){
$("messages").insertBefore(elem,$("messages").firstChild);
}else{
$("messages").appendChild(elem);
}
}
//メッセージ入力欄が空白でなければメッセージを送信する
function sendMessage(){
var message=$("message").value;
if(message==""){return;}
ws.send(message);
$("message").value="";
}
//初期化処理
function initial(){
//HTTPSで接続されている場合、WebSocketもセキュアにする
var protocol=(location.protocol=="https:")?"wss":"ws";
//port番号も込みで取得
var host=location.host;
//接続先URLの組み立て
var url=protocol+"://"+host+"/ws/";
//WebSocketのインスタンス化
ws=new WebSocket(url);
//WebSocketのイベントの登録
ws.addEventListener("open",onOpenWebSocket,false);
ws.addEventListener("close",onCloseWebSocket,false);
ws.addEventListener("message",onMessageWebSocket,false);
//ウィンドウを閉じたり画面遷移した時にWebSokcetを切断する
window.addEventListener("unload",onUnload,false);
}
//オンロード時のイベントに、初期化関数を定義
window.addEventListener("load",initial,false);
チャットサーバの起動
これでWebSocketを使ったチャットの実装は一通り完成しました。それでは、
サーバを起動する前に、
その後、
コンソールに
![図1 メッセージ送信側の画面 図1 メッセージ送信側の画面](/assets/images/dev/feature/01/websocket/0005/thumb/TH800_001.png)
![図2 メッセージ受信側の画面 図2 メッセージ受信側の画面](/assets/images/dev/feature/01/websocket/0005/thumb/TH800_002.png)
次回予告
次回は、