-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
关于 Hprose 3.0 通信协议设计方案的讨论 #6
Comments
可不可以内置客户端认证功能? |
要是能把一段byte[]数据变成本地调用就好了,谢谢 |
@xiaoqingping @orangeagain 你们的需求描述太过简单,我无法从中捕获到可以理解的信息。 你们可以把需要和解决方案写的详细一些吗?可以参照上面几个连接中的方案来写。 |
最好支持Angular。感觉十分好。还有能不能支持聊天功能。 |
Angular还是不要支持的好,耦合过重 |
我觉得3.0的通信协议会是一个Hprose protocol,基于这个协议会有多个现实方式,比如刚才 @MiyamuraMiyako 提到的KCP或者tcp、mq等。Hprose protocol应该抽象比较高级的功能,比如双向流、限流等。 |
@MiyamuraMiyako KCP 是用在 UDP 基础上实现了 TCP 吧,基于这种方式用 RPC 也太小众吧 -____- !! |
@Lao-liu 一方面是响应小马哥对于速度的追求,另一方面小众不小众其实无所谓,只要好用咱们就用咯。rpcx也用了kcp |
@MiyamuraMiyako 嗯,估计主要是 rpcx 是基于 golang 的并且已经有了 kcp-go, 所以比较容易吧。但是 Hprose 目前支持的语言比较多。如果只是基于 KCP 来跑 Hprose 服务的话,完全可以用 kcptun 架好内网,在它基础上去跑就行了。 |
@Lao-liu 你这么一说,我发现这么做也不错。没必要再单独实现了。 |
@tang6723 Angular 本来就支持。已经有好多人用 Angular + hprose 开发项目了啊。 |
能不能增加对 IDL 接口描述语言的支持。有点类似 WSDL 一样的,可以用来描述发布接口的入参、返回数据的类型等。这样便于开发 ^_^ |
@tang6723 https://www.jianshu.com/p/9758f28d7ba2 Angular 下直接用就行。 |
@Lao-liu IDL 比较难,而且 Hprose 最初就是为了实现不需要 IDL 的 RPC。在类型映射上 IDL 不够自由灵活,还会引入不同版本的接口不兼容的问题。要设计一套可选的,可以自由定义类型映射的,不会产生不同版本接口不兼容问题的 IDL 目前我没有想到该怎么来做。你可以试着来设计一套。 |
@MiyamuraMiyako 这个可以有,不知道对 Hprose 通信协议部分需不需要做修改。最好补充一下。 |
@andot 不需要改已有协议。只是底层协议的更换。 |
@MiyamuraMiyako 好的,那实现上就更方便了,基本上替换一下连接方式就行了。 |
@andot 我想简单了,我的想法只是增加一个通过反射方式对当前对外发布接口进行描述的功能。没考虑你那么复杂。 ^_^ |
想用在游戏上就必须有个接口,input |
@orangeagain 底层的传输协议可以是 HTTP、TCP、WebSocket,也可以换成 KCP。这些底层的用于传输的协议就是可以换的轮子。hprose 的远程调用、推送、反向调用部分的协议并不是轮子,它是整个车的主体部分。 |
应强调一致性,虽然是跨语言的,但是文档却是各个语言分开的,反而模糊了跨语言一致性的优点(如果跨语言不一致是很糟糕的结果)。文档应只有一份,强调一致的部分,不一致的部分不必要强调,语言只在示例中体现不同。文档一份只是形式要求,实质希望让使用者在概念上理解不同语言有一致的实现,不会有意外,从而放心使用。如果现有各个语言实现有不一致的,可以通过同一份文档来规范一致性,达不到基本一致性要求的语言可暂时放弃。另,我现在用protobuf+hprose在项目中解决问题,使用protobuf是因为有可持续的跨语言规范维护要求,也就是说项目需要idl来维护各个语言一致性,因为维护起来方便,idl有其实际意义,当然这和hprose无冲突,但却可以说明无需idl不能说是个太大的优点。grpc能支持的语言已经涵盖主流,golang和javacript已经支持的很完善了,hprose如果能在工程角度给开发带来更多帮助,使用更方便简洁,才能具备更大优势。 |
@OliverZou,你的想法很好,我当初也是打算把文档只写一份的,所以当初建了这样一个项目:https://github.com/hprose/hprose-doc |
hprose 3.0 除了最上面列举的那三个新功能以外,还会对之前的 RPC 协议部分做一些精简,取消一些使用率很低,但是实现却很复杂,甚至影响可扩展性的内容,比如目前已经决定要取消的包括“引用参数回传”和“批处理调用”。 Hprose 3.0 在实现中,还会将原来在核心中紧密耦合实现的功能,单独拿出来,作为中间件或编码器来实现。 比如 Hprose 协议编码解码部分在 hprose 3.0 中会作为单独的可替换编码器实现,这样可以通过替换编码器来直接将 Hprose 客户端、服务器变身成 JSONRPC 客户端、服务器,当然也可以替换成 protobuf、msgpack 等编码器,只要用户喜欢,用户可以替换成任何它们喜欢的编码器。 原来的单向调用,故障转移,推送等功能也单独做成了中间件,用户需要的时候,可以挂载它们,不需要则不需要挂载它们,这不但让 hprose 客户端和服务器的核心变得更小更快更稳定,而且更具有可扩展性。 当然,有得必有失,目前 Hprose 3.0 最大的问题是跟旧的版本(1.x 和 2.x 版本)不再完全兼容,因为增加了独立的头部,并取消了引用参数回传和批处理调用,所以在旧系统升级时,不能像原来一样可以单独升级客户端或服务器端,只能客户端和服务器一起升级。当然,这在实际使用中,应该也算不上一个太大的问题。 |
几个建议:
随笔,仅供参考。 |
另注:pb生成的各个语言类型和接口定义文件,在hprose中并不能直接适用,pb并不是简单生成pojo对象,命名也各有差异,需要做大量适配工作。 |
1、如果有些问题能够直接在 2.0 的基础上解决,就不会写 3.0 了。3.0 的目标就是把核心精简,把 2.0 里面太多不必要的东西从核心中去掉。保持核心的最简化,其它的功能都通过插件方式实现。 2、2.0 不能调用 3.0 的某些服务并不是单纯在 2.0 上升级就能解决的。比如 3.0 中,跟 TCP 绑定协议的修改,增加了 UDP 绑定协议,对推送协议的修改等等。这个即使在 2.0 上升级,也会造成老的 2.0 版本跟新的 2.0 版本不兼容。所以才会升级大版本号到 3.0,目的就是跟 2.0 严格区分开。 3、hprose 的设计目标是不需要定义服务接口。客户端接口的存在也仅仅是方便客户端调用,而不是为了跟服务器接口统一。这跟那些用 IDL 来统一接口的 RPC 服务从设计上就是不一样的。 4、对于 hprose 来说,不是所有的客户端语言都需要定义接口。事实上,大部分语言其实是不需要在客户端定义接口。需要定义接口才能方便使用的语言只有 Java、C#、Go 这类强类型语言。而对于 PHP、JavaScript、Dart、Ruby、Python、Lua 等等这些弱类型语言,客户端可以直接使用最自然的方式去调用,而不用定义什么接口。另外,hprose 的服务是不需要基于接口实现的,所以说『客户端必须再声明和服务器一样的接口』这是个伪问题,事实情况是,对于 hprose 来说,服务器端根本不需要专为 RPC 来定义任何接口,而客户端为方便调用而定义的接口也完全不需要跟服务器端的服务实现一样。即便是 C# 这种强类型语言,hprose 也强烈不推荐在客户端定义跟服务实现一致的接口,而是希望用户在客户端定义方便自己调用的接口,举个简单例子,比如 Hello 这样一个函数,服务器端实现可能是这样的: public string Hello(string name, ServiceContext context) {
return "Hello " + name + " from " + context. RemoteEndPoint.toString();
} 而客户端的接口方法定义最好是这样的: Task<string> Hello(string name); 这个调用接口跟服务器的实现接口完全不一样,服务器端同步实现的接口,客户端可以异步调用,服务器端有一个环境变量参数,而客户端完全不需要关心它。 如果用 IDL 来强行统一客户端和服务器端的接口,只会让服务器端不方便实现,让客户端也不方便调用。 这就是 hprose 为什么不使用 IDL 来统一接口的原因。 5、推送在 3.0 中不属于核心的功能,是以插件方式提供的。 6、这个目标是一致的。 |
谢谢回复。 关于服务接口,我也了解使用hprose的确是不需要定义服务接口的。”客户端必须再声明和服务器一样的接口“确实不准确,不能用’必须‘。这个问题应该这么来说: 1.客户端需要获取接口信息。客户端虽然可以不用定义接口,但需要获取接口信息。客户端和服务端开发协作中(不一定是一个团队或者公司,客户端甚至是客户),如果没有接口定义,客户端是如何知道服务端提供了哪些服务?如何了解具体api形态如何?即使是弱类型语言,依然也要知道有哪些什么样的服务吧。通过文档?文档不具备强制性,开发过程中难以保证客户端和服务端的一致性。(这种”一致性“,仅要求连接点和输入输出类型信息,未必要求调用方式的一致性,异步或者同步调用方式并不影响一致性),而idl本身就是语言无关的精确文档。 2.接口便利性是重要的,虽然不用定义接口,但如果使用不方便,不用定义接口就不能成为一个优势。而hprose的一个重要优势是接口使用便利。对于强类型语言,如果要自然方便的使用rpc接口,就需要在客户端定义接口。一般情况下没什么,但在客户端不是服务器团队甚至是客户的团队的情况下,接口易用性是要满足的,总不能让客户全调用invoke,从用户角度,invoke接口并不便利。总之,在接口多,语言多且持续维护的情况下,客户端为了便利性从而需要定义接口,但这样存在较大的不便性。 另外,以IDL来定义接口,未必就是强行统一客户端和服务端的接口的方方面面,idl的客户端代码生成完全可以存在多个版本的调用形式,定义相同的结构对象在不同语言的接口中,可以使用map或者object或者struct对象,依语言情况而用,hprose的io可以保证解析成功。所以idl编译生成的代码,只需要客户端能够访问到服务端的这个函数,服务端能获取参数即可,两端的调用参数形式上不要求一定完全一样,但接口信息类型信息总是要有的,这是idl编译工具的实现问题。必要的话在idl编译参数明确指定即可。 一家之言,仅供参考。 |
既然你的目的是通过 IDL 来生成不同语言的客户端调用接口。那么这个东西其实是独立于 Hprose 本身的一个附加工具,而不必作为 Hprose 的核心实现。后期如果有人有能力能够完成这个东西,就可以直接拿来用,并不需要对目前的 Hprose 做任何修改。 而且我不认为 IDL 可以有这种灵活的能力,如果有的话,那么早就有了,为什么这么多年,那么多大厂都没有做出这样的东西来?如果您认为这是一件很简单的事情,您完全可以按照您心目中最理想的方式来实现,然后把这个工具开源出来分享给大家,我觉得我没有这个能力。 我认为就算是客户端跟服务端不是一个团队的,那服务器的开发为了方便客户端调用,来为客户端定义一个可以方便使用的接口,也不是一件很难的事情了。这比起现在的 SDK 开发方式,要为每种语言都要单独编写客户端的 SDK 比起来,只要为几个强类型语言编写不同的调用接口定义不是已经方便很多了吗? |
Hprose 从 2008 年开始设计开发,从最初仅支持 HTTP,到后来增加了 WebSocket、TCP、UnixSocket 支持,以及在 Hprose 2.0 中增加了服务器推送等功能。这些都是在最初通信协议的设计下完成的。并未对通信协议本身做以修改。因此,Hprose 2.0 实现可以完全兼容 Hprose 1.x 的实现。
虽然 Hprose 2.0 目前已经满足了大多数开发者的需求,但是本着可以做到更好的目的,特开此贴,希望能够汇总广大 Hprose 开发者、用户及爱好者的意见建议和新需求,如果可能,将会把它们添加到下一版的 Hprose 3.0 中去。
所以,如果你有什么新的需求和想法,请不要吝啬你的文字,你可以开一个新的 issue,把你想说的内容用最详尽的方式表达出来,包括需求描述,应用场景描述,现有协议和实现为何无法满足,具体的改进和实现的细节等等。之后,你可以将你开的 issue 发到本贴的回复中。具体做法可以参照二楼回复。
格式不要求统一,但是请不要一句话带过,不然除了你自己,谁也不知道你想要的是什么。
欢迎大家积极参与讨论。
The text was updated successfully, but these errors were encountered: