Backbone.UndoをTypescriptで使ってみた その2

前回のサンプルではModelとView辺がうまく分離できていなかったので修正してみた

Backbone.Modelに状態を保存し、イベントを拾って、Undoなどの処理を行うようにしてみた

  • app.ts

  • index.html

AppModelクラスが状態を保存している。このBackboneModelに対し、各マウスイベントで発生したClickイベントの関数からModelに対し値をセット。Backboneのchangeイベントが発生するのでそれを拾って処理を行う感じ

Backboneをこのように使うのかどうかは不明。。自己流です

Backbone.UndoをTypescriptで使ってみた

backbone.undo.jsというBackboneJS用のUNDOモジュールが有ります。

http://backbone.undojs.com/

こちらをTypescriptで使用してみました。うまくいったのでサンプルを掲載しておきます

通常、Typescriptで既存のライブラリを使用する際には、Typescript用に型定義ファイルを作成してやる必要が有ります。

世の中にはいい人がいて、たいていのライブラリは型定義されていたりします。

https://github.com/borisyankov/DefinitelyTyped

しかし、今回使用するbackbone.undo.jsはまだこちらでは定義されていませんでしたので、適当に作成してみました。

https://github.com/anagotan/DefinitelyTyped/tree/master/backbone.undo

これを利用してUndo機能を実装してみます。

仕様としては、addボタンを押すと「name=0,value=0」のボタンが追加されていきます。update_nameおよびupdate_valueのボタンでランダムな数値に置き換わります。

これをもとにundoおよびredoを実装してみました。

  • index.html

  • app.ts

実行する際には別途,jquery,underscore.js,backbone.js を用意しておく必要が有ります

scalaのRedisクライアントbrandoを使ってみる(その3)

PlayFramework2.2でscalaのRedisクライアントbrandoを使用する際にはちょっと注意が必要です。

brando1.0はakka2.3対応らしく、Play2.2ではまだakka2.2の対応となっているためそのままでは動きません。

仕方がないのでbrando0.3にバージョンを落として使用します。

また前回のサンプルだと、キーに値がない場合にはエラーになってしまいます。

そこでbrando0.3を少し改造します

  • brand.Brando.scala

これで使いやすくなりました

scalaのRedisクライアントbrandoを使ってみる(その2)

前回brandoを使用してRedisの値をGETできたので今回はSubscribeしてみます。

Redisサーバ側から値をプッシュし、それをPlayのWebsocketでブラウザ側に流すため用に特化しています

試行錯誤をかなりしましたが意外と単純でした。

ポイントは起動するクラスをActorとして作成し、PubSubMessageをReceiveするだけです

これだけでした。

scalaのRedisクライアントbrandoを使ってみる

ちょっとはまったのでメモ。

scalaのRedisクライアントには何種類か有ります。

http://redis.io/clients

当初scala-redisを使っていたのですが、Pub/Subする際に、内部的にスレッドを生成しているようで、大量のPub/Subを作成したい場合(数千)にはOutOfMemoryで落ちてしまいます。

そこでActorモデルのbrandoを使用してみました。

ネット上にはほとんど情報もなくちょっとはまってしまったので記録しておきます

https://github.com/chrisdinn/brando

こちらからダウンロードしてsbt packageでJarを作成します。

あとakkaが必要なので2.3をダウンロードしておきます。

いろいろと試行錯誤し以下のコードでとれました

Pub/Subとかこれから確かめます

C言語でStringBufferもどきを作成してみる

c言語は速いのはいいのですが、いかんせん標準ライブラリ群が貧弱な面は否めません。

文字列周りの処理だとC++のSTLあたりを使用すれば簡単ですが、純粋にCで簡単に作成してみました

  • string_buffer.h

  • string_buffer.c

実行してみます

  • main.c

  • 実行結果

StringからEnumの作成

文字列からEnum型へ変換するサンプルです

Linuxでミリ秒まで取得

ansiのC言語で用意されているtime関数では現在時刻をミリ秒まで取得できません。そこでLinuxならではの取得方法の覚え書きです

gettimeofday関数を用いてミリ秒を取得します

以下のサンプルではミリ秒単位で現在時刻を取得し、2つの時間の差を求めています

PlayFramework+Redis+websocketでプッシュ配信(データ圧縮編)

Websocketに最近はまっています。

前回プッシュ配信をRedisのPub/Subを用いて実現した訳ですが、データ量が増えてくるとどうしても配信するデータを圧縮したくなります。

特にAWSなんかだと、従量課金となっていますので、データ転送量は少なければ少ないほど○

Websocket自体はまだデータの圧縮はサポートされていないとのことですので、自前でデータの圧縮伸長を実装してみました。

また、それだけではつまらないので、Reidsにチャンネルを作成し、ReidsのチャンネルごとにPub/Subする仕組みを入れています

図解するとちょっとわかりにくいですがこんな感じ

User別に作成したActorと、ユーザが選択したチャンネル(code1,code2,code3)別に作成したActorを別々に作成し、チャンネルがReidsから更新された際には、購読しているUserのActorへ更新をかけるという感じです

こうすることにより、チャンネル数がユーザ数より圧倒的に少ない場合には、Reidsに対するコネクションも削減でき、効率が良くなります。

  • route

  • Compress.scala

データ圧縮用に作成します。String型をZIP圧縮し、BASE64でエンコードします

  • UserActor.scala

  • Javascriptで解凍

JavaScriptでZIP解凍、Base64でコードするために↓からinfrate.js,base64.js,utf.jsなどをダウンロードしておきます。

http://www.onicos.com/staff/iz/amuse/javascript/expert/

サンプルの一式は以下においておきました

https://github.com/anagotan/play_websocket_compressed

PlayFramework+Redis+websocketでプッシュ配信を作成してみる

Websocketを使ったサンプルだとチャットが多いのですが、実際にはチャットのアプリを作ることはあまり有りません。

どちらかというとサーバ側から配信するというような用途が多いのではないでしょうか?

PlayframeworkのサンプルにはWebsocketを使ったサンプルが付属しています。

これを改造してサーバ側から配信できるように改造してみました

  • 環境
    • MacOS10.9
    • jdk1.7
    • playframework2.2
    • redis2.8.4
    • scala2.10
  • playframeworkのチャットサンプル

brewでインストールした場合にはこちらに入っているので、作業エリアにコピーしておきます

/usr/local/Cellar/play/2.2.1/libexec/samples/scala/websocket-chat/

  • unicast

一斉配信したい場合にはサンプルで採用されているbroadcastをそのまま使用してもいいのですが、今回は一対一通信で配信したいのでunicastを使用します。サンプルはこちらを参考にしました。

http://satoshi-m8a.github.io/blog/2013/05/18/scala-concurrent-unicast/

  • build.sbt

scalaからredisに接続するためにはscala-redisライブラリを使用します。そのためbuild.sbtに以下を記述します

  • conf/logger.xml

ログ出力用に追加します

  • conf/application.conf

redisの接続先をconfに書いておきます

  • models/ChatRoom.scala

モデルをscala-redisのテストコードを参考に修正します

これで準備完了

  • 実行

play runで実行し、ユーザ名部分にカンマ区切りでキーを入力します。このキーはカンマ区切りで複数入力可能で、このキーがredisのキーとなります。

画面が起動したら、a,b でログインしてみます

その後Reidsのコマンドで値を送ってみます

画面にa test が表示されます