温泉いって、Scalaで書かれたChirpUserStreams&WebSocketなTwitterクライアントをRev-WebSocketを使ってRubyで書いたった
あ…ありのまま 今 起こった事を話すぜ!
『おれはyuroyoroさんのScalaで書かれたChirpUserStreams&WebSocketなTwitterクライアントを改造していたと思ったら、いつのまにかRuby版を作っていた。』
な、何を言ってるのか(ry
7月18,19日に行われたCorona&Scala温泉開発合宿での自分の成果物の話です。
Scalaで書かれたChirpUserStreams&WebSocketなTwitterクライアントというのは、yuroyoroさんが5月10日に書かれた記事です*1。
今回の合宿では当初、これに改良を加えようと目論んでいました。
で、結果からいうと、Scalaの型パラメーターに敗北して、Ruby版を作成することに方針転換したと。
合宿中に行ったこと、成果
- Scala版のコードリーディング完了
- 各種サンプルのコードリーディング完了
- WebSocketの動作、仕様をある程度理解(含むJettyのWebSocket)
- ChirpUserStreamsの動作、仕様をある程度理解
- Ruby版途中までつくりかけ
- Scalaの型パラメーターを扱う上でのイディオムがさっぱりわかっていないという事が認識出来た事
合宿中に結局できあがらず、戻ってきてから完成させました。
サーバ部分のコードは以下。
########## chirp.rb ########## require 'net/http' require 'uri' require 'rubygems' require 'rev/websocket' Net::HTTP.version_1_2 # WebSocket chirp server class ChirpConnection < Rev::WebSocket # 接続されたら呼ばれる def on_open puts "WebSocket opened" send_message("server: Hello, WebSocket!") end # メッセージが届いたら呼ばれる def on_message(data) auth_hash=Hash[data.split('&').map {|s| s.split('=') }] Thread.start { chirp(auth_hash['username'],auth_hash['passwd']) do |str| send_message str end } end def chirp(id,pass) uri = URI('http://chirpstream.twitter.com/2b/user.json') buf ="" http = Net::HTTP.start(uri.host,uri.port) req = Net::HTTP::Get.new(uri.request_uri) req.basic_auth id, pass http.request(req) do |res| res.read_body do |body| buf += body until ( i = buf.index("\r\n")).nil? str = buf.slice!(0, i + 2).chomp unless str.size == 0 puts str puts "----------------------- #{i} Bytes. -------" yield(str) end end end end end def on_close puts "WebSocket closed" end end host = '0.0.0.0' port = ARGV[0] || 8081 server = Rev::WebSocketServer.new(host, port, ChirpConnection) server.attach(Rev::Loop.default) puts "start on #{host}:#{port}" Rev::Loop.default.run ########## chirp ########## #!/usr/bin/env ruby fork { load 'chirp.rb' exit 0 } require 'webrick' server = WEBrick::HTTPServer.new({ :Port => 8080, :BindAddress => '127.0.0.1', :DocumentRoot => File.dirname(__FILE__)+'/public'}) trap('INT') { server.shutdown } server.start
ruby chirpでサーバースタートします。
クライアント部分はyuroyoroさんのをほぼそのまま使用しました。
htmlとcssを持ってきてWebSocketでの接続先を8080から8081に変更したぐらいです。
ChirpUserStreamsへのアクセス部分はこちらからぱくらせてもらいました。
WebSocketサーバは、EventMachineベースのEM-WebSocketを使っているものが多いようなのですが、ちょうど合宿の前日にリリースされていたので、Rev-WebSocketを使用してみました。
参加メンバーの成果
Corona&Scalaらしく、Corona関係のネタが4つ、Scalaネタが2つでした。残りは私のRubyと、アイデア、企画の精査?でした。
Corona SDKはFireworksからCoronaに吐き出したりとか、3つ作られたiPhoneアプリは、3D時計アプリとか、プリクラアプリなどバラエティ豊かでした。
Scalaは環境セッティングの方と、武田さんの記事を参考に、AndroidアプリをScalaで動かすに挑戦された方でした。Android for Scalaは環境構築、確認用アプリのビルドだけでなく、既存のアプリをScalaで動かす所まで実現されていました。素晴らしい!