LingrRadar もどきを作り始めてみた
とりあえず、超適当版はこんな感じ
object lingr_test { import scala.io._ import scala.xml.parsing._ import scala.util.DynamicVariable import jp.ryugate.net.Http val LINGR_SERVER = "www.lingr.com" val APIKEY = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" val EMAIL = ("email", "xxxx@b.com" val PW = ("password", "himitsu") val NICKNAME = "hoge-san" val ROOMID = "ryugate" type Arg = Tuple2[String, String] val HTTP = new DynamicVariable[Http.Http](null) def req(method:(String, List[Arg]) => String, resource:String, args:List[Arg]) = { val res_xml = method(resource, args) ConstructingParser.fromSource(Source.fromString(res_xml),false).document } def session(apikey:String)(f:List[Arg] => Unit) = { val res = req(HTTP.value.post, "/api/session/create", List*1 println(session) try { f(session) } finally { HTTP.value.post("/api/session/destroy", session) } } def room(session:List[Arg], roomid:String, nickname:String)(f:(Arg,Arg) => Unit) = { val rid = ("id", roomid) val nname = ("nickname", nickname) val res = req(HTTP.value.post, "/api/room/enter", rid :: nname :: session) val ticket = ("ticket", (res \\ "ticket").text) val counter = ("counter", (res \\ "counter").text) println(ticket) println(counter) try { f(ticket, counter) } finally { HTTP.value.post("/api/room/exit", ticket :: session) } } def observe(session:List[Arg], ticket:Arg, counter:Arg):String = { val res = req(HTTP.value.get, "/api/room/observe", counter :: ticket :: session) val c = ("counter", (res \\ "counter").text) println(c) println((res \\ "text").text) observe(session, ticket, c) } def main(args:Array[String]) { Http.start(LINGR_SERVER) { http => HTTP.withValue(http) { session(APIKEY) { session => http.post("/api/auth/login", EMAIL :: PW :: session) room(session, ROOMID, NICKNAME) { (ticket, counter) => observe(session, ticket, counter) } } } } } }
上記で使っている、HTTPのラッパは以下のとおり
package jp.ryugate.net object Http { import java.io._ import java.net._ class Http(host:String) { var _read_timeout = 0 def read_timeout:Int = _read_timeout def read_timeout_=(timeout:Int) { _read_timeout = timeout } var _proxy_host = "" def proxy_host:String = _proxy_host def proxy_host_=(proxy_host:String) { _proxy_host = proxy_host } def makeargs(args:List[(String,String)]) = { val x :: xs = args val head = x._1 + "=" + x._2 xs.foldLeft(head) {(acc, v) => acc + "&" + v._1 + "=" + URLEncoder.encode(v._2, "UTF-8") } } def get(resource:String):String = { val url = new URL("http://" + host + resource) val con = url.openConnection.asInstanceOf[HttpURLConnection] if (_read_timeout > 0) con.setReadTimeout(_read_timeout) con.setRequestMethod("GET") val br = new BufferedReader(new InputStreamReader(con.getInputStream)) try { readContents("", (br.readLine _)) } finally { br.close } } def get(resource:String, args:String):String = get(resource+"?"+args) def get(resource:String, args:List[(String,String)]):String = get(resource, makeargs(args)) def post(resource:String, args:String):String = { val url = new URL("http://" + host + resource) val con = url.openConnection.asInstanceOf[HttpURLConnection] con.setDoOutput(true) val pr = new PrintWriter(con.getOutputStream()) try { pr.print(args) } finally { pr.close } if (_read_timeout > 0) con.setReadTimeout(_read_timeout) val br = new BufferedReader(new InputStreamReader(con.getInputStream)) try { readContents("", (br.readLine _)) } finally { br.close } } def post(resource:String, args:List[(String,String)]):String = post(resource, makeargs(args)) def readContents(acc:String, reader:()=>String):String = reader() match { case null => acc case s => readContents(acc + s, reader) } } def start(host:String)(f: Http => Unit) { val http = new Http(host) f(http) } }
問題点:
- 「hoge has joined」というシステムメッセージが出てしまう。(LingrRadarだと出ない)
- たまに、全メッセージが戻ってくることがある。
- たまに、接続が切れる。(もしかしたら、2分程度でタイムアウトさせて、もう一度APIを発行する必要があるのかもしれない)
予定: