Scala day 37 (scalapb)
project 目錄結構
build.sbt
import scalapb.compiler.Version.scalapbVersion
name := "hellopb"
scalaVersion := "2.11.12"
PB.targets in Compile := Seq(
scalapb.gen() -> (sourceManaged in Compile).value
)
libraryDependencies ++= Seq(
"com.thesamet.scalapb" %% "scalapb-runtime" % scalapbVersion,
"com.thesamet.scalapb" %% "scalapb-runtime-grpc" % scalapbVersion,
"io.grpc" % "grpc-okhttp" % "1.14.0",
"io.grpc" % "grpc-netty" % "1.14.0"
)
assemblyJarName in assembly := name.value + ".jar"
assemblyMergeStrategy in assembly := {
case PathList("META-INF", xs @ _*) => MergeStrategy.discard
case x => MergeStrategy.first
}
assembly.sbt
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.7")
scalapb.sbt
addSbtPlugin("com.thesamet" % "sbt-protoc" % "0.99.18")
libraryDependencies += "com.thesamet.scalapb" %% "compilerplugin" % "0.7.4"
hello.proto
syntax = "proto3";
package com.example.protos;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
執行 sbt compile
build 出來的 scala 程式會在下列路徑
GreeterImpl.scala
package ght.mi.hello
import com.example.protos.hello.{GreeterGrpc, HelloReply, HelloRequest}
import scala.concurrent.Future
class GreeterImpl extends GreeterGrpc.Greeter {
override def sayHello(req: HelloRequest) = {
val reply = HelloReply(message = "Hello " + req.name)
Future.successful(reply)
}
}
HelloWorldServer.scala
package ght.mi.hello
import com.example.protos.hello.GreeterGrpc
import io.grpc.{Server, ServerBuilder}
import scala.concurrent.ExecutionContext
object HelloWorldServer {
def main(args: Array[String]): Unit = {
val server = new HelloWorldServer(ExecutionContext.global)
server.start()
server.blockUntilShutdown()
}
private val port = 50051
}
class HelloWorldServer(executionContext: ExecutionContext) {
self =>
private[this] var server: Server = null
private def start(): Unit = {
server = ServerBuilder.forPort(HelloWorldServer.port).addService(GreeterGrpc.bindService(new GreeterImpl, executionContext)).build.start
sys.addShutdownHook {
System.err.println("*** shutting down gRPC server since JVM is shutting down")
self.stop()
System.err.println("*** server shut down")
}
}
private def stop(): Unit = {
if (server != null) {
server.shutdown()
}
}
private def blockUntilShutdown(): Unit = {
if (server != null) {
server.awaitTermination()
}
}
}
HelloWorldClient.scala
package ght.mi.hello
import com.example.protos.hello.{GreeterGrpc, HelloReply, HelloRequest}
import io.grpc.ManagedChannelBuilder
object HelloWorldClient {
def main(args: Array[String]): Unit = {
val host = "localhost"
val port = 50051
val channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext(true).build
val request = HelloRequest(name = "World")
val blockingStub = GreeterGrpc.blockingStub(channel)
val reply: HelloReply = blockingStub.sayHello(request)
println(reply)
}
}
測試
先執行 HelloWorldServer.scala 再執行 HelloWorldClient.scala
參考資料
scalapb