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关闭与客户端之间的连接。
-