Jetty8でWebSocketしてみた(蔵側)

どもー(´ω`)ノ Ramencozoです

前回の続き(Jetty8でWebSocketしてみた(鯖側))です(´ω`)
今回はWebSocketクライアントとなるAndroid端末側の実装について書き書きしますφ(´ω`)

必要なライブラリはこちら(´ω`)っ
・WebSocketライブラリ:weberknecht -> weberknecht-0.1.1.jar

このライブラリをAndroidなProjectフォルダに突っ込んで(新規でlibとかフォルダ作ってそこに置きます)、Build Pathの方の設定でAdd Jar Fileします(´ω`)
[2012/06/25 追記] ADT(Android Development Tools)プラグインに変更があったのか、外部ライブラリを置くフォルダは「libs」としたほうが良いようです。(Android Dependenciesに自動で内包されるようです)
逆に、別のフォルダに置いた場合、Build Path→Configure Build Path→Order and Exportのとこで該当ライブラリにチェック付けないとapkにライブラリが内包されないようです。

WebSocketクライアントなアプリは下記。画面に表示される MainActivity.java と、WebSocket接続の処理を行う WebSocketManager.java から成っています。


HelloWebSocketClient / MainActivity.java

package jp.ramensroom.hellowebsocketclient;

import de.roderick.weberknecht.WebSocketEventHandler;
import de.roderick.weberknecht.WebSocketMessage;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity {

// チャットログ用 ListView + ArrayAdapter
private ListView chatListView;
private ArrayAdapter chatArrayAdapter;

// テキスト送信用 EditText + Button
private EditText postEditText;
private Button sendButton;

// WebSocket Client
private WebSocketManager manager;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

chatArrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1);

chatListView = (ListView)findViewById(R.id.chat_listview);
chatListView.setAdapter(chatArrayAdapter);

postEditText = (EditText)findViewById(R.id.post_edittext);

sendButton = (Button)findViewById(R.id.send_button);

manager = new WebSocketManager();
manager.connect("ws://サーバIPアドレス:サーバポート/echo", new WebSocketEventHandler() {
@Override
public void onOpen() { // WebSocket接続確立時に呼ばれる
Toast.makeText(getApplicationContext(), "WebSocket Connected.", Toast.LENGTH_SHORT).show();
}

@Override
public void onMessage(WebSocketMessage message) { // WebSocketサーバからデータが送られてきた時に呼ばれる
final String msg = message.getText();

chatArrayAdapter.insert(msg, 0); // ListViewの先頭に最新のデータが来るように0番目へ挿入
}

@Override
public void onClose() { // WebSocket接続切断時に呼ばれる
Toast.makeText(getApplicationContext(), "WebSocket Disconnected.", Toast.LENGTH_SHORT).show();
}
});

sendButton.setOnClickListener(new OnClickListener() { // Buttonが押された時の処理
@Override
public void onClick(View v) {
final String msg = postEditText.getText().toString();

Toast.makeText(getApplicationContext(), "Message Sent.", Toast.LENGTH_SHORT).show();
manager.send(msg);
chatArrayAdapter.insert("me:" + msg, 0); // 自分の投稿であることを明記
postEditText.setText(""); // でもってEditTextの入力領域クリア
}
});
}
}

HelloWebSocketClient / WebSocketManager.java

package jp.ramensroom.hellowebsocketclient;

import java.net.URI;
import java.net.URISyntaxException;

import de.roderick.weberknecht.WebSocket;
import de.roderick.weberknecht.WebSocketConnection;
import de.roderick.weberknecht.WebSocketEventHandler;
import de.roderick.weberknecht.WebSocketException;

public class WebSocketManager{
private WebSocket webSocket;
private boolean connectState;

public WebSocketManager() {
connectState = false;
}

// WebSocketサーバとの接続確立メソッド
public void connect(String url, WebSocketEventHandler handler){
try {
URI uri = new URI(url);
webSocket = new WebSocketConnection(uri);
webSocket.setEventHandler(handler);
webSocket.connect();

connectState = true;
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (WebSocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

// WebSocketサーバへStringデータを送信するメソッド
public void send(String message){
try {
webSocket.send(message);
} catch (WebSocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

// WebSocket接続を切断するメソッド
public void close() {
try {
webSocket.close();
connectState = false;
} catch (WebSocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

// WebSocket接続がなされているかを確認するメソッド
public boolean isConnected(){
return connectState;
}
}

HelloWebSocketClient/res/layout / main.xml


実際に動作させた様子が下記画像の通りとなります(´ω`)っ
WebSocketServer (PC側, JDK1.6, Swing)


WebSocketClient (Android側)

こんな具合にPCとAndroid間でカンタンに双方向リアルタイム通信ができたっていう報告ですたヾ(*´ω`*)ノシ
ただ、なんかタイムアウトがけっこー起きるみたいなのでその辺タイムアウトする前に「生きてますよー」的なメッセージを定期的に投げたほうがいいかもしれませんね(´ω`)

それではまた(´ω`)ノ