• 简介
  • 执行顺序
    • 客户端的执行顺序
  • 跟踪调试
  • 运行时间统计
  • 协议转换

    简介

    有时候,我们可能会希望在远程过程调用中对通讯的一些细节有更多的控制,比如对传输中的数据进行加密、压缩、签名、跟踪、协议转换等等,但是又希望这些工作能够跟服务函数/方法本身可以解耦。这个时候,Hprose 过滤器就是一个不错的选择。

    Hprose 过滤器是一个接口,它有两个方法:

    1. inputFilter(data, context)
    2. outputFilter(data, context)

    其中 inputFilter 的作用是对输入数据进行处理,outputFilter 的作用是对输出数据进行处理。

    data 参数就是输入输出数据,它是 Uint8Array 类型的。这两个方法的返回值也是 Uint8Array 类型的数据,它表示已经处理过的数据,如果你不打算对数据进行修改,你可以直接将 data 参数作为返回值返回。

    context 参数是调用的上下文对象,我们在服务器和客户端的介绍中已经多次提到过它。

    执行顺序

    不论是客户端,还是服务器,都可以添加多个过滤器。假设我们按照添加的顺序把它们叫做 filter1, filter2, … filterN。那么它们的执行顺序是这样的。

    客户端的执行顺序

    1. +------------------- outputFilter -------------------+
    2. | +-------+ +-------+ +-------+ |
    3. | |filter1|----->|filter2|-----> ... ----->|filterN| |---------+
    4. | +-------+ +-------+ +-------+ | v
    5. +----------------------------------------------------+ +---------------+
    6. | Hprose Server |
    7. +-------------------- inputFilter -------------------+ +---------------+
    8. | +-------+ +-------+ +-------+ | |
    9. | |filter1|<-----|filter2|<----- ... <-----|filterN| |<--------+
    10. | +-------+ +-------+ +-------+ |
    11. +----------------------------------------------------+

    跟踪调试

    有时候我们在调试过程中,可能会需要查看输入输出数据。用抓包工具抓取数据当然是一个办法,但是使用过滤器可以更方便更直接的显示出输入输出数据。

    client.js

    1. function log(data) {
    2. console.log(data);
    3. return data;
    4. }
    5. var logfilter = {
    6. inputFilter: log,
    7. outputFilter: log
    8. };
    9. var client = hprose.Client.create("http://www.hprose.com/example/", ['hello']);
    10. client.addFilter(logfilter);
    11. client.hello("world", function(result) {
    12. console.log(result);
    13. });

    客户端输出


    1. Cs5"hello"a1{s5"world"}z
    2. Rs12"Hello world!"z
    3. Hello world!

    运行时间统计

    有时候,我们希望能够对调用执行时间做一个统计,对于客户端来说,也就是客户端调用发出前,到客户端收到调用结果的时间统计。对于服务器来说,就是收到客户端调用请求到要发出调用结果的这一段时间的统计。这个功能,通过过滤器也可以实现。

    client.js

    1. function stat(data, context) {
    2. if ('starttime' in context.userdata) {
    3. var t = Date.now() - context.userdata.starttime;
    4. console.log('It takes ' + t + ' ms.');
    5. }
    6. else {
    7. context.userdata.starttime = Date.now();
    8. }
    9. return data;
    10. }
    11. var statfilter = {
    12. inputFilter: stat,
    13. outputFilter: stat
    14. };
    15. var client = hprose.Client.create("http://www.hprose.com/example/", ['hello']);
    16. client.addFilter(statfilter);
    17. client.hello('world', function(result) {
    18. console.log(result);
    19. });

    客户端输出


    1. It takes 34 ms.
    2. Hello world!

    协议转换

    Hprose 过滤器的功能不止于此,如果你对 Hprose 协议本身有所了解的话,你还可以直接在过滤器中对输入输出数据进行解析转换。

    在 Hprose for JavaScript 中已经提供了一个现成的 JSONRPC 的过滤器。使用它,你可以将 Hprose 客户端变身为 JSONRPC 客户端。

    JSONRPC 客户端

    1. var client = hprose.Client.create("http://www.hprose.com/example/", ['hello']);
    2. client.filter = new hprose.JSONRPCClientFilter();
    3. client.hello("world", function(result) {
    4. console.log(result);
    5. });

    客户端只需要设置 filter 属性(或者用 addFilter 方法)为一个 JSONRPCClientFilter 实例对象,Hprose 客户端就马上变身为 JSONRPC 客户端了。不过需要注意一点,添加了 JSONRPCClientFilter 的客户端,是一个纯 JSONRPC 客户端,这个客户端只能跟 JSONRPC 服务器通讯,不能再跟纯 Hprose 服务器通讯了,但是跟 Hprose + JSONRPC 的双料服务器通讯是没问题的。

    - - -:warning: 注意:该文件并没有打包到 hprose.js 中,如果需要请单独引用 src/JSONRPCClientFilter.js。- - -

    Hprose 过滤器的功能很强大,除了上面这些用法之外,你还可以结合 Hprose 中间件来实现更为复杂的功能。不过这里就不再继续举例说明了。

    原文:

    https://github.com/hprose/hprose-js/wiki/Hprose-%E8%BF%87%E6%BB%A4%E5%99%A8