あーアニメ見てない。平日1本ずつでも見ないとまずい。 めんどうなのでいっそ今期アニメ休みにして見ないという手もあるが、まあそこまでたまってるわけでもないので毎日1本ずつ見ていけばよかろう。
読みたい本がたまってるのはどうしたもんかね……。
Azure Storage Tableのトランザクション処理をしようとおもってCloudTable.ExecuteBatch
を調べてたんだけど、よく考えたらこれテーブル跨いだバッチ実行できなくね?
パーティションが同じ必要があるとかあったけど、テーブルが同じじゃないといけないなんて制限書いてなかったと思うけどなーといろいろ調べてみると、REST APIドキュメントの頭の方に一文だけ書いてあった。気付かねーよ。 REST APIのサンプル見る限りでは各操作のURIさえいじればテーブル跨いで実行できそうなのでできるものとばかり思っていたが、おそらく文法的には出来ても実際には上手く実行されないんだろうなぁ。いずれにしても.NETクライアントでは実行できるインターフェース無いし。
テーブル跨いだトランザクション処理ができないと困るんだがどうしたものか。 やっぱりおとなしくSQL Serverに移行するか、諦めるかだな。……諦める?!その手があったか。
競合して多少おかしなことになっても動いてる分には大したことにはなりそうにもない。 所詮三日間だけ動かすイベントの余興だし適当でいいや。
ということで排他制御は諦めた。
そろそろサーバに設置してみないと不安だな。 Azureだからそんなに難しくないはず……とやってみると発行自体は手順通りにやるだけで簡単だった。 やたらと時間かかるなぁと思ったら13MiBもあるパッケージを上げてたので配信しながらでは上り帯域が厳しいようだ。 小さいサイトだから13MiBしかなくて済んでるけど、でかいサイトは困りそう……と思ったけどそうなったらTFSやGitから発行というのをやればいいのかもしれない。
発行はできたはずなんだがなぜかAzure Webのアプリを開いてみるとアプリを作り始めましょう的なチュートリアルページが開かれる。あれー?いろいろ調べた結果、なぜかクラウドサービス1……もといComputeの方に配置されてるようだ。確かにWebの発行プロファイル指定したらダメだって言われてあれーと思いつつ違うのを指定した気はするが……。Workerロールが含まれてたからだろうか。まあいいや。
ではとComputeの方のURLを開いてみるとアクセスできない。なんかサーバに到達してないような。ふっしぎー。 ログとか見る方法がよくわからんなーといいつつリモートデスクトップで入ってIISの設定辺りを見てみるとサーバ内からはアクセスできた。 ということはアプリは正常に動いてはいるのか。 しばらく眺めているとアプリが8080ポートで動いてるように見える。ふとURLにポート8080を指定してみるとアクセスできた!こいつかー。 Webロールのエンドポイントの設定でポート80を設定しておかないといけないようだった。 もー、チュートリアルの手順に入れといてよー……と思ったけどこれ俺がWCFサービステンプレートでプロジェクト作ったせいだわ。
残りのでかい問題はイベント用サイトにこれを埋め込めるかだな。 埋め込むにあたって何が問題になるか整理してみると、イベントサイトのドメインで動いてるスクリプトからゲームサーバのSignalRに通信接続できるかだ。 うわこれ難しそう。 だが調べてみると、SignalRはクロスドメイン通信対応機能が最初からあるようだ。やたー。
サーバでRouteHub
を実行する時に渡すSignalRの設定でクロスドメイン通信を有効にするってのがあるのでこれをやって、
クライアントでは$.connection.url = 'http://example.com/signalr'
のようにゲームサーバのURLを接続前に指定しておく。
これだけで出来た。便利だなー。
さて分かってる大きな問題はたぶんこれで全部解決したのであとは作り込み。もう時間ないけどなー。 他の問題はもう分からんので起きてから対処する方向で考えよう。完成したのをひやひやしながら眺めてるだけより、問題起きてリアルタイムで直してる方が楽しいもんな!
Windows Azure Cloud ServiceはWorkerロールやWebロールのホスティングをする物のようだ。Azure Webとの区別がよくわからんし、そもそも名前がひどすぎる。 ↩
ここしばらくはまたコードの整理をしていた。
プラグインはDLLからPlugin属性がついたクラスを読み込んで、実装してるインターフェースによってPeerCastオブジェクトの適当な場所にくっつけてたんだが、柔軟性がなくて綺麗じゃないし、プラグインで設定の読み込みとかしようと思ってもできない。 UI関係のプラグインはStartとStopメソッドがあって、アプリ開始・終了時にそれらが呼ばれて適当な処理をするようになっているんだが、よく考えたら全部この形でいいんじゃないかと思いついたのでそうした。読み込む側がやっていたPeerCastオブジェクトの適当な場所にくっつける処理を、プラグインクラスのStartメソッドでプラグイン側がやる形になった。
見てたチャンネルが終了したら通知してほしいというのがあったので実装したい。しかしロジック側から通知を表示するインターフェースがないな。ユーザーインターフェースプラグインに追加してやろう。
Windows.Forms版とWPF版は通知表示が簡単に実装できたけどHTML UIはどうしたものか。 SignalRはOWINという.NET版Rackみたいなのを使ってホストできるみたいだけどさすがに大仰すぎるかな。 SignalRで使ってるWebSocketというものを直接使って……いやそれは大変すぎる。Server Sent Eventsというものを使えないか調べてみるとこれは簡単そう。つか単なるlongpollじゃないですか。IEでは使えないみたいだけど単なるlongpollなのでJavaScriptで代替実装がいくらかあるので使えそう。やるならこれがいいかな。
Server Sent Eventsはよさそうだが、一瞬でできるほど簡単なわけでもないし、単純に1秒毎のポーリングでも問題ないので今のところはポーリングにしよう。ポーリングでさくっと実装してみたが、各ページに入れなきゃいけないのがちょっと面倒だな。まあページ数少ないからやりゃいいだけなんだが。
通知ができるようになったらUIからアップデートを分離して通知できるようにもしたい。しかしアップデートUIの表示もあるからこれはそこまで単純でないのが悩ましい。
上り帯域が細い環境で配信する時に、直下にリレーできないノードがついちゃって困るんだがPeerCastStationでは自動切断無いのかと相談を受けた。まあ無いんだけど。
無いとはいっても欲しいのはADSL使ってる俺もよくわかるのでそろそろ実装したい。しかし各種PeerCast改造版についてるリレーできないノードの自動切断ってあんまり役に立たなかったり変に切られまくっちゃったりするのが困るところ。何かいい方法はないものか。
PeerCastの自動切断機能は、ポートが開いてないノード(俗に言う赤)が接続された時に一定時間で切断する、帯域が足りなくてリレーできないノード(俗に言う紫)が接続された時に一定時間で切断する、といった機能だったはず1。
この機能の問題は、まず第一に一度接続してからじゃないと切れないことだ。 本当はリレーリクエストが来た時点でお断りできればいいんだが、PeerCastのプロトコル上、一旦リレーを受け入れないと帯域やポート開放状況のデータが受け取れないので判別できないので残念なことになる。
リレーがいっぱいの状況だと問答無用でお断りするため自分がトラッカー(配信者)だと、直下にリレーできないノードが付いてリレーが一杯になっちゃう→他のリレーできるかもしれないノードが来るけどもういっぱいなのでお断り→リレーできないノードを切る→けどまたリレーできないノードが再接続に来る→無限ループ、というろくでもない結果になりかねん。あーでもPeerCastだと切ったあと一時的にブラックリスト的なのに入れてるのかな。いやでもブラックリストも一旦接続受け入れないと機能しないはずだなぁ。
もう一点の問題は、べつに切る必要なくても切っちゃう問題。リレーの枝が全部いっぱいで詰まると困るからリレーできないノードはなるべくお断りしたいんだが、逆に言うと詰まってさえなければリレーできないノードがいても問題ない。これをあんまり厳しくしちゃうと、PeerCastは自分の使える帯域が自己申告性なので、切られたくないがために実際使えるより多い帯域幅を申告してリレー可能なように見せかける輩が出てきてしまう。だから詰まってなければ、リレー不可ノードの切断はあんまりやるべきじゃないんだよねぇ。
そんなわけでどうしたものか困ったところなんだけど、リレー不可ノードは他のリレー要求が来た時点で切るようにしたらどうかと提案された。リレーがいっぱいになるまではそのまま接続しておいて、いっぱいになったところでさらに誰かが接続に来たらリレーできないノードを切って新しく来た奴を優先してやろうという話だ。なるほどこれはいい。新しく来たノードがやっぱりリレー不可という可能性はあるけど、その場合も損はしてないので問題ないな。
リレー要求がされたら一刻も早くレスポンスを返すべきだと思い込んで、レスポンス返す前に他のリレーをどかす処理を入れるなんて思い付かなかったが、確かに切るくらいの余裕は全然あるな。この方向で考えてみよう。
プラグインとして入れるのは難しいからコア機能になりそうだけど大丈夫かな。特によくない影響ってのも思い浮ばないからたぶん標準機能として入れても大丈夫だと思うけどなー。
最近PeerCastStationしか使ってない上に、自動切断は以前から使ってなかったからうろ覚えだ。 ↩