えへへ
うふふ
ヒデタロ先輩にご紹介にあずかりました、
acha_maroことアチャマロです!
早速ですが、
前にPHPでTwitterからストリーミングを中継して、 flashで受け取るというのをやりました。
まずは、Twitterからのストリーミングを各クライアントのソケットに流し込むところまで。
AMS.php(AchamaroMediaServer)
<?php
// Twitter User ID
$id = "userid";
// Twitter User Pass
$pass = "password";
// Twitter Streaming API
$streamingAPI = "http://stream.twitter.com/1/statuses/filter.json";
// Listenポート
$port = 5080;
// APIパラメータ
$context = stream_context_create
(
array(
'http' => array(
'method' => "POST",
'header' => "Authorization: Basic " . base64_encode($id . ":" . $pass) . "\r\n" .
"Content-type: application/x-www-form-urlencoded" . "\r\n",
'content' => http_build_query(
array(
'track' => "#achamaro"
// #achamaroを含むツイートを受信
)
)
)
)
);
// Listen開始
$serversocket = socket_create_listen($port);
socket_set_nonblock($serversocket);
// クライアントソケット格納用配列
$clients = array();
// ストリーミング受信開始
$stream = fopen($streamingAPI, 'r', false, $context);
while ($json_text = fgets($stream)) {
// 新規クライアント接続
while (false !== ($tmp_socket = @socket_accept($serversocket))) {
$clients[] = $tmp_socket;
}
// JSONデコード
$json = json_decode($json_text, true);
if (!$json) continue;
// とりあえずツイートを各クライアントへ送信
foreach ($clients as $client) {
@socket_write($client, $json['text'], strlen($json['text']));
}
}
?>
ここまでは割といろんなブログで公開されているので
とくに問題なく進みました。
動作確認は
コンソールから
$php AMS.php
別コンソールから
$telnet localhost 5080
後は、ツイッターで「#achamaro」をつけてつぶやいた瞬間に
2個目のコンソールに表示されればOKです。
次にflash側です。
まず、flashでツイート表示用のテキストフィールドを作成し、
インスタンス名に「tBox」と名付けました。
表示先の準備が出来たのでActionScriptを書いていきます。
socket.as ※socket.asはドキュメントクラスです。
import flash.display.MovieClip;
import flash.net.Socket;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
public class socket extends MovieClip
{
// ソケットオブジェクト
private var sk:Socket;
/**
* コンストラクタ
*/
public function socket()
{
// AMSに接続
this.sk = new Socket("192.168.1.31",5080);
// 接続確立イベントハンドル
this.sk.addEventListener(Event.CONNECT,connectHandler);
// セキュリティエラーイベントハンドル
this.sk.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler);
// 受信イベントハンドル
this.sk.addEventListener(ProgressEvent.SOCKET_DATA,progressHandler);
}
/**
* セキュリティイベントハンドラー
*/
private function securityErrorHandler(event:SecurityErrorEvent)
{
// デバッグ
this.tBox.appendText("securityError: " + event);
}
/**
* 接続確立イベントハンドラー
*/
private function connectHandler(event:Event)
{
// デバッグ
this.tBox.appendText("connect:" + event);
}
/**
* 受信イベントハンドラー
*/
private function progressHandler(event:ProgressEvent)
{
// デバッグ
this.tBox.appendText("progress: " + event);
// 受信内容表示
readResponse();
}
/**
* 受信内容表示
*/
private function readResponse()
{
var str:String = this.sk.readUTFBytes(this.sk.bytesAvailable);
this.tBox.appendText(str);
}
}
flashで実行してみて受信できたのでパブリッシュ!
複数のブラウザで受信してみようとサーバにあげてみたところ
securityError: [SecurityErrorEvent type="securityError" bubbles=false cancelable=false eventPhase=2 text="Error #2048: セキュリティサンドボックス侵害 : http://192.168.1.31:1002/socket.swf は 192.168.1.31:5080 からデータを読み込めません。"]
というエラーが。。。
試しにクロスドメインXMLを置いてみましたがダメ。。。
as3 + socket とかでググっていると
どうやらポリシーファイルというクロスドメインとは別ものを
置いてあげる必要があるみたいでした。
※Flashのソケットポリシーファイルを参考にさせて頂きました。
どうやらflashが843番ポートを覗きに来るので
ソケットポリシーファイルを返してあげないといけないようです。
早速ソケットポリシーファイル作成
poricy.xml
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" to-ports="5080"/>
</cross-domain-policy>
次に843番ポートでporicy.xmlを返すPHPプログラムを組みます。
poricy.php
<?php
$xml = file_get_contents('poricy.xml');
$port = 843;
$server = socket_create_listen($port);
while (true) {
$client = @socket_accept($server);
@socket_write($client, $xml, strlen($xml));
@socket_close($client);
}
socket_close($server);
?>
AMS.phpもやったし簡単^ω^v
コンソールからporicy.phpを実行!
$php poricy.php
PHP Warning: socket_create_listen(): unable to bind to given adress [13]: Permission denied in /var/www/socket/htdocs/poricy.php on line 6
むむむ!
AMS.phpの時はエラーとか出なかったのに。。。
そうえいばポート1000番以内はどうのこうのとか聞いた事がある気がしたので、
試しにrootで実行
エラーなし!
ブラウザのキャッシュクリアして再読み込み
無事受信できました。