创建客户端

创建客户端有两种方式,一种是直接使用构造器函数,另一种是使用工厂方法 create

使用构造器函数创建客户端

hprose.Client 是一个抽象类,因此它不能作为构造器函数直接使用。如果你想创建一个具体的底层网络协议绑定的客户端,你可以将它作为父类,至于如何实现一个具体的底层网络协议绑定的客户端,这已经超出了本手册的内容范围,这里不做具体介绍,有兴趣的读者可以参考 hprose.HttpClienthprose.TcpClienthprose.WebSocketClient 这几个底层网络协议绑定客户端的实现源码。

hprose.HttpClienthprose.TcpClienthprose.WebSocketClient 这三个函数是可以直接使用的构造器函数。它们分别对应 http 客户端、tcp 客户端和 WebSocket 客户端。

  1. new hprose.HttpClient([uri[, functions[, settings]]]);
  2. new hprose.TcpClient([uri[, functions[, settings]]]);
  3. new hprose.WebSocketClient([uri[, functions[, settings]]]);

这两个构造器的参数格式是相同的。开头的关键字 new 也可以省略,但最好不要省略。

构造器中包含了 3 个参数,这 3 个参数都可以省略。

当 3 个参数都省略时,创建的客户端是未初始化的,后面需要使用 useService 方法进行初始化,这是后话,暂且不表。

第 1 个参数 uri 是服务器地址,该服务器地址可以是单个的 uri 字符串,也可以是由多个 uri 字符串组成的数组。当该参数为多个 uri 字符串组成的数组时,客户端会从这些地址当中随机选择一个作为服务地址。因此需要保证这些地址发布的都是完全相同的服务。

第 2 个参数 functions 是远程函数名集合。它可以是单个函数名的字符串表示,也可以是多个函数名的字符串数组,还可以是一个对象。

第 3 个参数 settings 用于初始化客户端的设置。它可以初始化客户端的以下设置:

  • failswitch
  • timeout
  • retry
  • idempotent
  • keepAlive
  • byref
  • simple
  • useHarmonyMap
  • filter
  • binary
    这些设置都有对应的客户端设置方法,这里暂不解释,在后面介绍设置方法时,再分别介绍。

例如:

  1. var client = new hprose.HttpClient(uri, 'hello', { timeout: 20000 });

创建的 client 对象上,就有一个叫 hello 的远程方法,并且客户端的超时被初始化为 20000ms。

这个 hello 方法可以直接这样调用:

  1. var result = client.hello('world');

再举一例:

  1. var client = new hprose.HttpClient(uri, ['hello', 'sum']);

这样创建的 client 对象上,就有两个远程方法,他们分别是 hellosum

  1. var client = new hprose.HttpClient(uri, {
  2. user: ['add', 'update', 'del', 'get']
  3. });

这样创建的 client 对象上,就有一个叫 user 的对象,在这个 user 对象上有 4 个方法,他们分别是 add, update, del, get

可以这样调用:

  1. var result = client.user.get(id);

注意:这里的 user.adduser.updateuser.deluser.get 分别对应服务器端发布的别名为:user_add, user_update, user_deluser_get 方法。

服务器端的别名可以通过 _ 分隔成好几段,每一段都可以转换为 . 调用的方式。

另外,对象和数组方式还可以组合使用,例如下面这个复杂一点的例子:

  1. var functions = {
  2. user: ['add', 'update', 'del', 'get'],
  3. order: [ 'add', 'update', 'del', 'get', {
  4. today: [ 'add', 'udate', 'del', 'get' ],
  5. yesterday: [ 'add', 'udate', 'del', 'get' ],
  6. tomorrow: [ 'add', 'udate', 'del', 'get' ]
  7. }]
  8. };
  9.  
  10. var client = new hprose.HttpClient(uri, functions);

在上面的例子中:client.order.add 方法对应服务器端的 order_add 方法,而 client.order.today.add 方法则对应服务器端的 order_today_add 方法。

当然,如果方法有很多,像这样一个一个都列出来,或许有些麻烦。所以这个函数列表可以省略。

如果省略的话,想要直接使用方法名调用需要在 client 对象的 ready 方法回调中才能使用,例如:

  1. var hprose = require('hprose');
  2. var client = new hprose.HttpClient(uri);
  3. client.ready(function(proxy) {
  4. proxy.hello('world', function(result) {
  5. console.log(result);
  6. });
  7. });

因为当省略函数名列表时,客户端会向服务器端请求这个函数名列表,当获取到之后才会将这些函数绑定到客户端对象上。而获取的过程是异步的,因此需要使用 ready 方法。

在省略函数名列表的情况下,对于 user_add 这样的方法,在旧版本中是不能使用 user.add 的方式调用的。但是从 hprose-js v2.0.33 版本之后,也可以使用 user.add 这种方式了。

通过工厂方法 create 创建客户端

  1. hprose.Client.create(uri[, functions[, settings]]);
  2. hprose.HttpClient.create(uri[, functions[, settings]]);
  3. hprose.TcpClient.create(uri[, functions[, settings]]);
  4. hprose.WebSocketClient.create(uri[, functions[, settings]]);

与构造器函数不同,工厂方法 create 可以在 hprose.Client 上被调用,它会根据 uri 的协议来决定创建什么类型的客户端。

create 方法与构造器函数的参数一样,返回结果也一样。但是第一个参数 uri 不能被省略。

create 方法与构造器函数还有一点不同,create 会检查 uri 的有效性(是指格式是否有效,而不是指服务器是否可以连通),而构造器函数不会检查。

因此,除非在创建客户端的时候,不想指定服务地址,否则,应该优先考虑使用 create 方法来创建客户端。

使用 hprose.Client.create 方法还有个好处,当你变更底层通讯协议不需要修改代码,只需要修改 uri 地址就可以了,而 uri 地址可以通过各种方式动态加载,因此更加灵活。

uri 地址格式

HTTP 服务地址格式

HTTP 服务地址与普通的 URL 地址没有区别,支持 httphttps 两种协议,这里不做介绍。

WebSocket 服务地址格式

除了协议从 http 改为 ws(或 wss) 以外,其它部分与 http 地址表示方式完全相同,这里不再详述。

TCP 服务地址格式

  1. <protocol>://<ip>:<port>

<ip> 是服务器的 IP 地址,也可以是域名。

<port> 是服务器的端口号,hprose 的 TCP 服务没有默认端口号,因此不可省略。

<protocol> 表示协议,它可以为以下取值:

  • tcp
  • tcp4
  • tcp6
  • tls
  • tcps
  • tcp4s
  • tcp6s
    tcp 表示 tcp 协议,地址可以是 ipv6 地址,也可以是 ipv4 地址。

tcp4 表示地址为 ipv4 的 tcp 协议。

tcp6 表示地址为 ipv6 的 tcp 协议。

tlstcps 意义相同,表示安全的 tcp 协议,地址可以是 ipv6 地址,也可以是 ipv4 地址。如有必要,可设置客户端安全证书。

tcp4s 表示地址为 ipv4 的安全的 tcp 协议。

tcp6s 表示地址为 ipv6 的安全的 tcp 协议。