Asterisque* is lightweight bidirectional RPC with asynchronous messaging framework, protocol and implementation for P2P distributed system.
To build asterisque* JAR library, you may clone asterisque* GitHub repository and build asterisk_2.10-0.1.jar by sbt package.
$ git clone https://github.com/torao/asterisk.git $ cd asterisk $ ./sbt packageOr, you can also run directory by using sbt run to specify following sample code of bi-directional RPC.
import com.kazzla.asterisk._ import java.net.InetSocketAddress import scala.concurrent.{Await,Future,Promise} import scala.concurrent.duration.Duration import scala.concurrent.ExecutionContext.Implicits.global import scala.util._ // 1) Simple implementation is to define scala trait or java interface // as IDL to agree interface statically between client and server. // Those every methods must has @Export(function-id) annotation and // `Future` return type. trait Sample1 { @Export(10) def greeting(name:String):Future[String] } trait Sample2 { @Export(10) def surround(text:String):Future[String] } // 2) Implementation class of interfaces is used as remote service on // server node. You may calculate result asynchronously after returning // `Future` immediately. class Sample1Impl extends Service with Sample1 { def greeting(name:String) = Session() match { case Some(session) => val promise = Promise[String]() session.bind(classOf[Sample2]).surround(name).onComplete { case Success(str) => promise.success(s"hello, $str") case Failure(ex) => promise.failure(ex) } promise.future case None => Promise.failed(new Exception()).future } } class Sample2Impl extends Service with Sample2 { def surround(text:String) = Promise.successful(s"*$text*").future } object SampleImpl { def main(args:Array[String]):Unit = { // 3) Instantiate client and server nodes that use Netty as messenger bridge. val node1 = Node("node 1").serve(new Sample1Impl).bridge(netty.Netty).build() val node2 = Node("node 2").serve(new Sample2Impl).bridge(netty.Netty).build() def close() = Seq(node1,node2).foreach{ _.shutdown() } // 4) The server listen on port 9999 without any action on accept. node1.listen(new InetSocketAddress(9999)) // 5) Client retrieve `Future[Session]` by connecting to server port 9999. val future = node2.connect(new InetSocketAddress(9999)) val session = Await.result(future, Duration.Inf) // 6) Bind remote interfaces from client session. val sample = session.bind(classOf[Sample1]) // 7) Call remote procedure and action asynchronously. sample.greeting("asterisk").onComplete { case Success(str) => println(str) close() case Failure(ex) => ex.printStackTrace() close() } } }$ ./sbt run [info] Set current project to asterisk (in build file:/Users/torao/git/asterisk/) [info] Compiling 1 Scala source to /Users/torao/git/asterisk/target/scala-2.10/classes... [info] Running SampleImpl hello, *asterisk* [success] Total time: 11 s, completed 2014/02/03 5:53:31All sources and related resources are available under Apache License Version 2.0.