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を発行する必要があるのかもしれない)
予定: