Author Archive

, , , | No Comments | 6月 17th, 2010

 WebSocketを使って、@projecthl2先生といっしょにリアルタイム連動お絵かきチャットを作ってみました。

おえかきちゃっと♥

 WebSocket 速いです!リアルタイムで同期しているので、数人でやると、毎秒サーバと50回とかやりとりしてるのだけど (1回の通信はおそらく100bytesくらい)、サーバ側はほとんどCPU食ってないみたいですね。すごぃ。もし AJAX とか使うとすると、毎秒50回とかサーバにリクエスト飛ばそうとか絶対考えないよ。2窓開いてみると、遅延はほぼ0で通信できてることが分かります。

 WebSocket は、やってみたところでは文字列しか送れなさそうなので、今までAJAXでJSON扱ってたようなものは文字列にして送る必要がありました。

JSON.stringfy({x:100, y:100})

みたいにしてサーバに送って、サーバからJSONを文字列にしたものを送って

JSON.parse(event.data)

的な感じにJSONを得てみました。

 お絵かき部分と、チャット部分でWebSocketを使っています。サーバ側のWebSocket部分は em-websocket を使いました。EventMachine を使った WebSocket 実装みたいです。WebSocket はシンプルでした。EventMachine の使い方を調べるのに時間がかかった。。

 お絵かき部分は、canvas を使っています。ファイルをロードの部分は XMLHttpRequest Level2 を使っています。最初は、FileAPI を使って実装すればサーバ経由せずにファイルロードできてウマー!! と思ったけど、まだ Firefox でしか使えないみたいなので、あきらめました。Twitterに投稿っていう部分は、canvas から toDataURL() で canvas に描かれたデータが Base64エンコードされたものを取って、そいつをサーバ側に送って保存しています。今までの XMLHttpRequest ってファイルをサーバに送信出来なかったので、無理矢理 iframe 使ったりとか頑張っていたけど、ファイルが送れるようになってすごい便利そうです。使い方は今までのものと大して変わらないみたいですし。

 
 HTMLを生成する部分は sinatra ちゃんです。sinatra ちゃん可愛いよ。センスいいと思う。

 2日で作られたものなので、例外処理とかあんまりしてなぃ。。でも2日でこのくらいのもの出来るとは、高機能なHTMLですねー

| No Comments | 5月 25th, 2010

Controller周り

ファイル名を指定して render

render("Account/signup.html")

app/views/Account/signup.html を render する。どうも、同じコントローラでも、ディレクトリから書き始めなければ読んでくれないみたい。

viewに変数を渡す

render(name, email)

app/views/Account/signup.html を render する。どうも、同じコントローラでも、ディレクトリから書き始めなければ読んでくれないみたい。

Model周り

テーブル名を変更する

Rails的なテーブル名を使いたい場合は、@Table を使って設定出来るみたいです。基本的に、JPA関連を調べればJAVAの情報でもだいたいそのまま使えるようです。

@Entity
@Table(name="users")
class User(
...

普通のfind

Rails的な感じで書けるようだ。

User.find("login = ? AND password = ?", login, password).first

.first を.all にすると配列になる。

.first だと Option[モデル] という型で返ってくる。

| No Comments | 5月 13th, 2010

まずは環境構築のメモ。

優しい Scala の育て方を参考に、新しめのバージョンを入れてみた。

scalaのインストール

Macならportでもインストール出来るが2010-05-13現在2.7が入るので、Scala公式サイトから2.8RCをソースからインストールする。

% curl -O http://www.scala-lang.org/downloads/distrib/files/scala-2.8.0.RC2.tgz

解凍したら、 bin に PATH を通す。

scala と打つと、起動されます。

% scala
Picked up _JAVA_OPTIONS: -Duser.language=en
Welcome to Scala version 2.8.0.RC2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_17).
Type in expressions to have them evaluated.
Type :help for more information.
 
scala>

対話型のシェルが立ち上がります。とりあえず、 :q として終了します。

playframeworkのインストール

% curl -O http://download.playframework.org/1.1-nightly/play-1.1-unstable-r881.zip

解凍して、解凍した play-1.1-unstable-r881 自体にPATHを通します。

Scala モジュールのインストール

playframework を scala で動かせるように、モジュールをインストールします。

% play install scala

バージョン 0.3 のモジュールがインストールされます。

プロジェクト作成

% play new ecpplus --with scala

ecpplus というディレクトリ名で、プロジェクトが作成されます。

起動

% play run

http://localhost:9000/ で立ち上がります。

http://localhost:9000/@documentation でドキュメントが見られるみたいですが、JAVAで記述する場合のドキュメントのようなので、 Scala版のドキュメント を読んでみようと思います。

とりあえず、環境構築はここまで。

友達が JAVA のバージョン 1.5 だと動かなかったようなので、1.6にしておけばOKみたいです。

| No Comments | 3月 8th, 2010

nginx.conf で、下記のような感じで、 large_client_header_buffers の 値を上げれば良いみたいです。

    client_header_buffer_size 64k;
    large_client_header_buffers 4 64k;

| No Comments | 2月 23rd, 2010

Shop has_many Items という状況のとき、とある shop が持っている items を、下記のように取ることが出来ます。それに対して、条件を設定することも出来ます。

>> @shop.items 
=> [Item id:21 shop_id: 1, Item id: 22, shop_id: 1, ....]
>> @shop.item.find_all_by_category("CPU") 
=> [Item id:23 shop_id: 1, Item id: 26, shop_id: 1, ....]

そこで、同様にとある Shop の Items を全部 delete_all にしようとしたのですが、DELETE されるのではなく、外部キーにNULLがセットされるという挙動になっています。

>> @shop.items.delete_all

とすると

  Item UPDATE (3.0ms)   UPDATE `items` SET shop_id = NULL WHERE (shop_id = 1 AND id IN (22,23,24,25,26))

のようになります。

Rails の API を見ると

# File vendor/rails/activerecord/lib/active_record/base.rb, line 897
897:       def delete_all(conditions = nil)
898:         sql = "DELETE FROM #{quoted_table_name} "
899:         add_conditions!(sql, conditions, scope(:find))
900:         connection.delete(sql, "#{name} Delete all")
901:       end

みたいになっているのですが、Dynamic Scopes はまた別のところで定義されているっぽいです。

>> @shop.items.destroy_all

としてみると、下記のように DELETE になりますが、SQL が発行されまくってるのでだめぽいです。そもそも destroy は、destroy をトリガーにしている各種処理をしてから DELETE が行われるので、そもそも delete とは意味合いが違うというので仕方ないです。

Item Destroy (3.0ms)   DELETE FROM `items` WHERE WHERE id = 21
Item Destroy (3.0ms)   DELETE FROM `items` WHERE WHERE id = 22
Item Destroy (3.0ms)   DELETE FROM `items` WHERE WHERE id = 23

ふつうに Item.delete_all を呼ぶかなぁ

download the hurt locker  
UA-682965-1