协议转换

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

在 Hprose for PHP 中已经提供了现成的 JSONRPC 的过滤器。使用它,你可以将 Hprose 服务器变身为 Hprose + JSONRPC 双料服务器。也可以将 Hprose 客户端变身为 Hprose + JSONRPC 双料客户端。

main.go

  1. package main
  2.  
  3. import (
  4. "fmt"
  5.  
  6. "github.com/hprose/hprose-golang/rpc"
  7. "github.com/hprose/hprose-golang/rpc/filter/jsonrpc"
  8. )
  9.  
  10. func hello(name string) string {
  11. return "Hello " + name + "!"
  12. }
  13.  
  14. type HelloService struct {
  15. Hello1 func(string) (string, error) `name:"hello" userdata:"{\"jsonrpc\":true}"`
  16. Hello2 func(string) (string, error) `name:"hello"`
  17. }
  18.  
  19. func main() {
  20. server := rpc.NewTCPServer("")
  21. server.AddFunction("hello", hello).AddFilter(
  22. jsonrpc.ServiceFilter{},
  23. LogFilter{"Server"},
  24. )
  25. server.Handle()
  26. client := rpc.NewClient(server.URI()).AddFilter(
  27. jsonrpc.NewClientFilter("2.0"),
  28. LogFilter{"Client"},
  29. )
  30. var helloService *HelloService
  31. client.UseService(&helloService)
  32. fmt.Println(helloService.Hello1("JSONRPC"))
  33. fmt.Println(helloService.Hello2("Hprose"))
  34. fmt.Println(helloService.Hello1("World"))
  35. client.Close()
  36. server.Close()
  37. }

为了清楚的让大家看到通讯的实际内容,我在这里引用了前面的 LogFilter

而且在这里我们还可以看到,在客户端使用了自定义的 userdata 标记,这个标记中包含了那段 JSON 数据表示开启 JSONRPC 模式,这个是 jsonrpc.ClientFilter 中定义的,您如果有兴趣,可以去看该结构体的实现。

下面我们来看运行结果:


  1. Client: {"id":1,"jsonrpc":"2.0","method":"hello","params":["JSONRPC"]}
  2. Server: {"id":1,"jsonrpc":"2.0","method":"hello","params":["JSONRPC"]}
  3. Server: {"id":1,"jsonrpc":"2.0","result":"Hello JSONRPC!"}
  4. Client: {"id":1,"jsonrpc":"2.0","result":"Hello JSONRPC!"}
  5. Hello JSONRPC! <nil>
  6. Client: Cs5"hello"a1{s6"Hprose"}z
  7. Server: Cs5"hello"a1{s6"Hprose"}z
  8. Server: Rs13"Hello Hprose!"z
  9. Client: Rs13"Hello Hprose!"z
  10. Hello Hprose! <nil>
  11. Client: {"id":2,"jsonrpc":"2.0","method":"hello","params":["World"]}
  12. Server: {"id":2,"jsonrpc":"2.0","method":"hello","params":["World"]}
  13. Server: {"id":2,"jsonrpc":"2.0","result":"Hello World!"}
  14. Client: {"id":2,"jsonrpc":"2.0","result":"Hello World!"}
  15. Hello World! <nil>

从运行结果中我们看到,当客户端调用 Hello1 方法时,使用的是 JSONRPC 通讯方式,而调用 Hello2 方法时,使用的是 Hprose 通讯方式,但是都成功调用了服务器端的同一个 hello 方法。当然你还会发现,其实 Hprose 通讯数据量只有 JSONRPC 通讯数据量的一半,所以如果没有特殊需要,完全不必使用 JSONRPC 来代替 Hprose。Hprose 就是你最好的 RPC 首选。

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