« 2008年11月 | トップページ | 2009年3月 »

2009年2月16日 (月)

RED5をやってみた。

6年位前にFlash Communication Server MXでマルチユーザーの実験をしたことはあったけど、未だに案件でそういうコンテンツを作る機会が無く。。
企画の段階で話が出たりすることもあるけど、結局サーバの問題でNGになることが多いなあ。
(クライアントのサーバをいじれない、他に専用サーバを用意する費用がない、等)

でも今年やっと仕事でマルチユーザのコンテンツができるかもしれない!
その場合はFlash Media Serverという選択肢はあるんだけど、やっぱり高いんで無料でできるRED5を試してみました。

インストールやら設定なんかは他のサイトを参考にやってみました。
ただサーバサイドのプログラムの作成のとこで、参考サイト通りにやってもできずに悩みました。。

<参考>
http://coelacanth.heteml.jp/site/flash_red5/article_4
http://www.sonicjam.co.jp/soniclabs/?p=46
http://www.thinkit.co.jp/article/152/3/3.html

このへんで書かれてるのはスクリプトを書くところまでだけど、実際はjar形式でエクスポートし、「lib」フォルダに格納しなければいけませんでした。
バージョンが違うのかな?それかなんか設定がおかしい?まあ動いたからいいや。

以下、参考サイトに書いてあることだけど個人的なまとめ。
サーバーサイドのJavaです。

クライアントからサーバサイドの関数を呼ぶと引数で「IConnection conn」が渡される。
これを使って呼び出し元のクライアントの関数を実行できる。

if (conn instanceof IServiceCapableConnection) {
	IServiceCapableConnection sc = (IServiceCapableConnection) conn;
	sc.invoke("recvID", new Object[]{id, msg});
}

接続しているクライアント全部の関数を実行するのは下記のとおり。

IScope scope = Red5.getConnectionLocal().getScope();
Set roomClients = scope.getClients();
Iterator iter = roomClients.iterator();
while ( iter.hasNext() ) {
	IClient client = (IClient) iter.next();
	Set connset = client.getConnections();
	Iterator itcon = connset.iterator();
	while (itcon.hasNext()) {
		conn = itcon.next();
		if (conn instanceof IServiceCapableConnection) {
			IServiceCapableConnection sc = (IServiceCapableConnection)conn;
			sc.invoke("recv", new Object[]{getClients().size()});
		}
	}
}

誰かが接続してきた時に呼ばれる関数。
この中で接続者全員に現在の接続者数を渡してあげればリアルタイムで接続人数を更新できる。
接続人数は「getClients().size()」で取得できる。
ただし、この中ではまだ新しく接続した人の分はプラスされてないので+1してから返すといい。

public boolean appConnect( IConnection conn , Object[] params ){}

誰かが切断した時に呼ばれる関数。
この中で接続者全員に現在の接続者数を渡してあげればリアルタイムで接続人数を更新できる。
接続人数は「getClients().size()」で取得できる。
ただし、この中ではまだ切断した人の分はマイナスされてないので-1してから返すといい。

public void appDisconnect(IConnection conn) {}

MySQLを使う時は以下の通り。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

Statement stmt = null;
try {
	Class.forName("com.mysql.jdbc.Driver");
	Connection db_conn = DriverManager.getConnection("jdbc:mysql://localhost/dbname", "username", "password");
	stmt = db_conn.createStatement();
	ResultSet rs = stmt.executeQuery("SELECT * FROM id");
	while(rs.next()) {
		//1行ずつ処理するのかな
		//取得するのがStringなのかIntなのか等で関数が変わる
		id = rs.getInt("num");
	}
	stmt.close();
	stmt = null;
	db_conn.close();
	db_conn = null;
	updateID(id+1);
} catch (SQLException ex) {
	//log.debug("SQLException: " + ex.getMessage());
	//log.debug("SQLState: " + ex.getSQLState());
	//log.debug("VendorError: " + ex.getErrorCode());
} catch (Exception e2) {
	//log.debug("Exception: " + e2.getMessage());
}

UPDATEとかINSERTのときは↓こんな感じで。

import java.sql.PreparedStatement;

PreparedStatement updateNum = db_conn.prepareStatement("UPDATE id SET num = ? ");
//SQL文の中の「?」に対して何を指定するか
//第一引数は「何番目の?」に対してか。
//第2引数は「その?に何を入れるか。
updateNum.setInt(1, id);
updateNum.executeUpdate();

てか今年初だ。今年はがんばります。。

| | コメント (0) | トラックバック (0)

« 2008年11月 | トップページ | 2009年3月 »