Hprose RPC 3.0 协议规范

发布于 2020-10-28 12:38:37 字数 2987 浏览 1663 评论 0

Hprose RPC 3.0 协议相比之前的版本做了简化。现在仅保留以下几个标记:

  • 0x43('C'): RPC 调用
  • 0x52('R'): RPC 结果
  • 0x45('E'): RPC 错误
  • 0x48('H'): RPC 头部
  • 0x7A('z'): 结束

函数名列表

RPC 服务器可以发布一个或多个函数/方法。每个函数/方法拥有一个名字。函数/方法名以字符串的形式表示。

在 hprose 3.0 中,函数名列表的返回形式被简化为与普通的 RPC 调用结果的返回形式相同。

如果客户端的请求包体为空,或者只发送一个结束标记 `z` 到服务器端,而没有其它数据。那么服务器端应该返回函数名列表。

另外,如果客户端调用的方法名为一个特殊字符 `~`,没有参数,那么服务端也返回函数名列表。

也就是说,服务器端将函数名列表作为一个名为 `~` 的远程函数发布。选择 `~` 是为了防止与任何正常函数/方法名称发生冲突。

例如,如果服务器端发布了两个函数,一个是 'hello',另一个是 'md5',那么函数名列表应该以如下形式返回:

Ra3{u~s5"hello"s3"md5"}z

Hprose RPC 服务器支持发布缺失的函数/方法。这表示如果客户端调用一个服务器端不存在的函数/方法,且服务器端设置有一个统一的处理器,那么该请求可以被这个统一的处理器所处理。这个统一的处理器函数使用名称 `*` 来表示它。

例如:

Ra2{u~u*}z

函数/方法名和缺失函数/方法统一处理器可以被一起发布。

例如:

Ra4{u~u*s5"hello"s3"md5"}z

Hprose 服务器端必须实现函数名列表函数。

RPC 调用

RPC 调用由客户端发起,例如:

Cs5"hello"a1{s5"world"}z            # result = client.hello("world");

你可以传递 0 个或多个参数,例如:

Cs3"sum"a3{012}z                    # result = client.sum(0, 1, 2);

如果没有参数,参数列表可以省略,例如:

Cs9"deleteAll"z                    # client.deleteAll();

Hprose RPC 3.0 取消了引用参数传递。

Hprose 发布的函数/方法名是不区分大小写的。例如上面的例子中,服务器端定义的函数/方法名是 "Sum",但是在客户端,可以使用 'sum','Sum' 或 'SUM' 来调用它,这都没问题。

在标记 'C' 之后,标记 's' 表示函数/方法名,标记 'a' 表示参数列表。标记 'z' 表示调用结束。

函数/方法名和参数列表是独立的对象序列化。因此它们具有独立的整数引用编号。

Hprose RPC 3.0 也取消了批量调用支持。

RPC 应答

Hprose RPC 应答由服务器端返回,例如:

string hello(string str) {
    return "Hello " + str + "!";
}

int sum(int a, int b, int c) {
    return a + b + c;
}
Cs5"hello"a1{s5"world"}z            # 客户端调用

Rs12"Hello world!"z                 # 服务器端应答

Cs3"sum"a3{012}z                    # 客户端调用

R3z                                 # 服务器端应答

返回值可以是 hprose 支持的任意类型。

如果发布的函数/方法不具有返回值,则返回值为 Null。

RPC 错误

如果在远程函数/方法执行过程中发生错误,hprose 服务器应该以如下格式返回错误信息:

E<error_message>z

<error_message> 是序列化的错误信息字符串。例如:

void errorExample() {
    throw new Exception("This is a error example.");
}
Cs12"errorExample"z               # 客户端调用

Es24"This is a error example."z   # 服务器端应答

RPC 头部

RPC 头部标记是 Hprose RPC 3.0 中新增的,它是可选项。

RPC 头部用来从客户端到服务端,或从服务端到客户端,传递参数和结果以外的数据。它的格式如下:

H<map>

它不会单独被发送,如果它存在,那么它总是被放在请求之前或者响应之前。例如:

m2{s4"user"s3"Tom"s5"token"s8"abcdef78"}Cs5"hello"a1{s5"world"}z
m1{s13"authenticated"t}Rs12"Hello world!"z
m1{s13"authenticated"f}Es24"This is a error example."z

形式化定义

ABNF:

end = %x7A

function-name = string

function-arguments = list

rpc-header = %x48 map

rpc-call = [rpc-header] %x43 function-name [function-arguments] end

rpc-result = [rpc-header] %x52 serialize-data end

rpc-error = [rpc-header] %x45 string end

rpc-reply = rpc-error / rpc-result

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84961 人气
更多

推荐作者

醉城メ夜风

文章 0 评论 0

远昼

文章 0 评论 0

平生欢

文章 0 评论 0

微凉

文章 0 评论 0

Honwey

文章 0 评论 0

qq_ikhFfg

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文