5.8 Provider间数据交换

Limax通过客户端隧道方式支持信任Provider间安全数据交换,具体的数据内容由Provider自己解释。


  • 5.8.1 基本框架


    • 客户端隧道

      通常的服务器间数据交换需要在服务器间建立网络连接,与客户端隧道方式有很大不同,这里作一比较。

        客户端隧道 服务器直连
      大量数据 不适合 适合
      服务器防火墙 不需要 服务器网络拓扑越复杂,防火墙越复杂,现实运营环境下,网络与服务器分属不同部门管理,防火墙配置随服务器配置调整通常不现实,更不用说跨组织机构的协同了。
      服务器信任关系 通过证书实现 也可以通过证书,没有实现的版本
      客户数据传输 简单。客户端连通两端服务器后可以执行即时传输。客户端也可以暂存数据,执行非即时传输。 复杂。服务器间连接采用传输时连接,还是持久连接是两难问题。客户端终究需要介入传输过程的协调,需要复杂流程。

    • 数据安全

      1. 通过证书方式划定信任域,信任域内的服务器可以安全交换数据。详见附录《PKIX支持》《Key分发系统》

      2. 通过隧道的数据通过外部数据方式编码。详见附录《外部数据》


    • 数据标签

      1. 隧道数据的交换过程是一个异步过程

      2. 客户端服务器(可能是所有参与服务器)首先需要执行协商过程,协商结果产生了隧道交换Session。完整的理解,label就是一次隧道交换过程的SessionId。

      3. 实际上,绝大多数应用,不需要那么复杂的交换行为,可以重新解释label,简化应用开发。例如,标记应用数据的类型,直接决定目标ProviderID,等等。


  • 5.8.2 数据交换基本流程

    1. 客户端服务器协商,决定信任域,决定数据标签,在服务器端打包应用数据。这一步骤取决于应用实现。

    2. 服务器发送数据标签和隧道数据。

    3. 客户端收到数据标签和保护过的隧道数据,根据协商结果,转发数据或者暂存之后转发。

    4. 接收数据的服务器用数据标签与解码后的应用数据执行异步回调。回调过程取决于应用实现。


  • 5.8.3 服务器开发

    • 隧道异常

      隧道操作时可能出现各种异常,用limax.provider.TunnelException表示,这些异常分为4种类型,使用枚举limax.provider.TunnelException.Type描述,分别是

      1. NETWORK,网络操作时出现异常。

      2. CODEC,编解码异常,通常是数据被篡改。

      3. EXPIRE,隧道数据过期,源服务器将过期时间编码到被保护数据中,目的服务器用自己的当前时间校验该过期时间,失败抛出这一异常。

      4. LABEL,标签异常,源服务器明文传送标签时,同时将标签编码到被保护数据中,如果客户端执行转发时修改了标签,目的服务器校验时将抛出这一异常。

      TunnelException.getType() 可以获取异常的类型。对于NETWORK,CODEC类型,可以通过TunnelException.getException()获取导致TunnelException的异常。


    • 发送数据

      完成客户端服务器的协商,准备好信任域、数据标签、应用数据之后,通过4个可选方法发送数据。

      1. limax.provider.View.tunnel(long sessionid, java.net.URI group, int label, Octets data) throws TunnelException;

      2. limax.provider.View.tunnel(long sessionid, int label, Octets data) throws TunnelException;

      3. limax.provider.SessionView.tunnel(java.net.URI group, int label, Octets data) throws TunnelException;

      4. limax.provider.SessionView.tunnel(int label, Octets data) throws TunnelException;

      第一个方法为基础版本,sessionid决定了参与隧道的客户端,group为信任域(见附录《Key分发系统》),label为数据标签,data为应用数据。SessionView上保存有客户端的sessionid,所以SessionView上的方法省略了sessionid参数。调用缺省group的方法时使用服务器配置的defaultGroup作为信任域,详见运营配置。

      隧道与View没有任何联系,之所以把隧道方法放在View上,完全是为了编程方便。Provider编程时,所有操作都应该在View上完成,包括协商过程。在特定的View上完成协商,准备好参数之后,直接在该View上执行tunnel即可。


    • 接收数据

      Provider实现limax.provider.ProviderListener时,并列实现limax.provider.TunnelSupport接口。


          public interface TunnelSupport {
              void onTunnel(long sessionid, int label, Octets data) throws Exception;
              default void onException(long sessionid, int label, TunnelException exception) throws Exception {
                  throw exception;
              }
          }
          

      实现onTunnel方法,即可收到客户端转发过来的标签与应用数据。onTunnel方法在sessionid对应的线程上调度,调用同一用户相关的方法是线程安全的。

      解码数据的过程可能抛出CODEC,EXPIRE,LABEL类型的TunnelException,这样的异常可以通过实现onException方法截获。

      默认的onException方法重新抛出这个异常,将导致Provider记录错误日志,并且使用错误码ErrorCodes.PROVIDER_TUNNEL_EXCEPTION关闭与客户端之间的连接。


    • 注意事项

      不支持TunnelSupport的Provider也可以发送隧道数据,这样的Provider接收到隧道数据后,记录错误日志,使用错误码ErrorCodes.PROVIDER_TUNNEL_EXCEPTION关闭与客户端之间的连接。


上一页 下一页