Score
0
Watch 8 Star 17 Fork 1

Windoze / vertx-kotlin-rpcKotlinWTFPL

Join us
Explore and code with more than 2 million developers,Free private repositories !:)
Sign up
用Kotlin实现的极简的Vertx RPC框架,同时支持Java和Kotlin。 spread retract

Clone or download
README.cn.md 6.50 KB
Copy Edit Web IDE Raw Blame History
徐辰 authored 2019-03-01 17:09 . Update README.cn.md

Vertx Kotlin RPC over EventBus

CircleCI Download

极简的Vertx/Kotlin RPC框架。

开始

Maven包已发布到jCenter,请先按照说明配置maven或gradle的设置。

Maven:

<dependency>
    <groupId>codes.unwritten</groupId>
    <artifactId>vertx-kotlin-rpc</artifactId>
    <version>0.6</version>
    <type>pom</type>
</dependency>

Gradle:

compile 'codes.unwritten:vertx-kotlin-rpc:0.6'

在Kotlin中创建RPC service

import codes.unwritten.vertx.kotlin.rpc.RpcServerVerticle

//...

// 只要方法的签名匹配,服务可以不用实现用于定义接口的interface
class HelloSvcImpl {
    // 方法可以是suspend,也可以不是
    fun hello(name: String): String = "Hello, $name!"
}

// ...

vertx.deployVerticle(RpcServerVerticle("test-channel")
    .register("hello", HelloSvcImpl()))

在Kotlin中调用RPC service

import codes.unwritten.vertx.kotlin.rpc.getServiceProxy

// ...

// 服务接口定义
interface HelloSvc {
    // 成员函数必须是suspend,否则在调用的时候会抛出异常
    suspend fun hello(world: String): String
}

// ...

// 创建服务的Proxy对象
val svc: HelloSvc = getServiceProxy(vertx, "test-channel", "hello")
// 调用RPC服务
assertEqual("Hello, world!", svc.hello("world"))

在Kotlin中创建HTTP RPC service

import io.vertx.core.Vertx
import io.vertx.ext.web.Router
import io.vertx.ext.web.handler.BodyHandler
import io.vertx.kotlin.coroutines.CoroutineVerticle
import codes.unwritten.vertx.kotlin.rpc.HttpRpcHandler

// ...
class SomeVerticle: CoroutineVerticle() {
    override suspend fun start() {
        // ...
        val router = Router.router(vertx)
        
        // 必须打开BodyHandler
        router.route().handler(BodyHandler.create())
        
        // 只支持POST method
        router.post("/some-path").handler(HttpRpcHandler().register("hello", object {
            fun hello(name: String): String = "Hello, $name!"
        }))
        // 启动HTTP server
        // ...
    }
}

在Kotlin中调用HTTP RPC service

import codes.unwritten.vertx.kotlin.rpc.getHttpServiceProxy

interface HelloSvc {
    // 成员函数必须是suspend,否则在调用的时候会抛出异常
    suspend fun hello(name: String): String
}

// ...

// 用指定的URL创建服务的Proxy对象
val svc = getHttpServiceProxy<HelloSvc>(vertx, "http://127.0.0.1:8080/some-path", "hello")
// 调用HTTP RPC服务
assertEqual("Hello, world!", svc.hello("world"))

在Kotlin中调用JSON RPC service

import codes.unwritten.vertx.kotlin.rpc.HttpRequest
import codes.unwritten.vertx.kotlin.rpc.JsonRpcException
import codes.unwritten.vertx.kotlin.rpc.QueryParam
import codes.unwritten.vertx.kotlin.rpc.getHttpJsonRpcServiceProxy

interface DemoSvc {
    // 成员函数必须是suspend,否则在调用的时候会抛出异常
    // HttpRequest annotation可以用了定制映射
    // 缺省的方法是POST,缺省路径是方法名
    @HttpRequest(method = HttpMethod.GET, path = "comments")
    suspend fun getComments(postId: Int): List<Comment>
}

// ...

// 用指定的URL创建服务的Proxy对象
val svc = getHttpJsonRpcServiceProxy<PostmanSvc>(vertx, "https://postman-echo.com/")
// 调用JSON RPC服务
context.assertTrue(svc.getComments(1).isNotEmpty())

Query Param示例:

interface DemoSvc {
    @HttpRequest(method = HttpMethod.POST, path="somepath")
    // QueryParam annotation表明这个参数是query parameter而不是body的一部分,也可以指定参数名称
    // foo3将会作为body的一部分被发往server
    suspend fun someMethod(@QueryParam foo1: String, @QueryParam("foo2") arg2: String, foo3: String): SomeResponse
}

在Java中创建RPC service

import codes.unwritten.vertx.kotlin.rpc.RpcServerVerticle;

// ...

// 实现类不返回Future<T>,直接返回T
public class HelloSvcImpl {
    public String hello(String name) {
        return "Hello, " + name + "!";
    }
}

// ...

vertx.deployVerticle((new RpcServerVerticle("test-channel"))
    .register("hello", new HelloSvcImpl()));

在Java中调用RPC service

Java没有suspend函数,所以服务接口中的每个方法必须返回Future<T>而不是T

import io.vertx.core.Future;
import static codes.unwritten.vertx.kotlin.rpc.ServiceProxyFactory.getAsyncServiceProxy;

// ...

// 方法必须返回Future<T>而不是T
interface AsyncHelloSvc {
    Future<String> hello(String world);
}

// ...

AsyncHelloSvc svc = getAsyncServiceProxy(vertx, "test-channel", "hello", AsyncHelloSvc.class);
svc.hello("world").setHandler(ar -> {
    if (ar.succeeded()) {
        assertEquals("Hello, world!", ar.result());
    } else {
        // Error handling
    }
});

在Java中创建HTTP RPC service

(略)

在Java中调用HTTP RPC service

Java没有suspend函数,所以服务接口中的每个方法必须返回Future<T>而不是T

import io.vertx.core.Future;
import static codes.unwritten.vertx.kotlin.rpc.AsyncServiceProxyFactory.getAsyncHttpServiceProxy;

// ...

// 方法必须返回Future<T>而不是T
interface AsyncHelloSvc {
    Future<String> hello(String world);
}

// ...

AsyncHelloSvc svc = getAsyncHttpServiceProxy(vertx, "http://127.0.0.1:8080/some-path", "hello", AsyncHelloSvc.class);
svc.hello("world").setHandler(ar -> {
    if (ar.succeeded()) {
        assertEquals("Hello, world!", ar.result());
    } else {
        // Error handling
    }
});

Notes

  • JSON RPC使用Jackson进行序列化和反序列化。
  • 所有其它的参数和返回值都由Kryo进行序列化和反序列化,请参阅文档以了解更多的细节。
  • Java反射API不能获取方法的参数名称,而这是JSON RPC必须的功能,所以JSON RPC目前无法支持Java。如果你有什么好主意请告诉我。

TODO

  • 支持方法重载
  • RPC调用跟踪
  • JSON RPC支持路径参数

Comment ( 0 )

Sign in for post a comment

Kotlin
1
https://gitee.com/windoze/vertx-kotlin-rpc.git
git@gitee.com:windoze/vertx-kotlin-rpc.git
windoze
vertx-kotlin-rpc
vertx-kotlin-rpc
master

Help Search