基于XML和MINA2构建多系统的通讯服务
曾经有这样一个需求,来自公网(互联网)上的前端请求发送到内网系统A,内网系统A需要通过一个渠道系统处理,渠道系统处理之后,将结果反馈给内网系统A,内网系统A处理之后再反馈给客户端,客户端然后在通过一定的途径发送请求到第三方系统。
一:设计思想
这个系统作为多个外部业务系统的一个渠道;对外围系统提供统一的通讯服务,同时由于各种历史原因,它需要和安装互联网上各个地方的客户端进行连接服务。也就是说对于业务系统,它是一个底层的通讯服务系统,对于各个客户端来说,它又是一个上层的服务应用。
那么整个数据的流转如下:

图一
上图中客户端是发布在互联网的,而业务系统和渠道服务系统是发布在内网,属于内部通讯。
二:多个SERVER的通讯处理
方式一:
大家知道MINA2的通讯机制,是采用责任链的设计模式,在服务启动的时候,将日志,业务处理,线程等增加进去,在所有的报文过来的时候都会按照链式的结构一个节点一个节点的去处理:
如下图是SERVER端的一个处理流程,本系统将会启动两个SOCKET SERVER,这两个SERVER分别处理来自业务系统的请求和处理来自客户端的请求。

图二
如上图所示,所有的客户端和服务端的交换都需要经过上述转换,如日志,编码/解码,加密/解密等。所有的数据交换均采用XML报文的格式。
由于TCP/IP传输的时候,无法确定报文的边界,那么在报文的头上面需要加入固定格式的长度。如果你设置成1,2,4,那么就很方便了,在MINA2中有提供现成的方法判断报文。
如图一所示,系统中两个通讯服务端需要进行通信,特别是由业务系统发过来经过渠道系统的业务模块处理之后需要发送给另外一个SOCKET服务,那么这个时候如何处理?
在MINA2中两个SOCKET SERVER进行通讯,可以采用虚拟机内部的管道的方式。在MINA2的源码包里面自带了这个例子:
IoAcceptor acceptor = new VmPipeAcceptor(); VmPipeAddress address = new VmPipeAddress(8080); // Set up server acceptor.setHandler(new TennisPlayer()); acceptor.bind(address); // Connect to the server. VmPipeConnector connector = new VmPipeConnector(); connector.setHandler(new TennisPlayer()); ConnectFuture future = connector.connect(address); future.awaitUninterruptibly(); IoSession session = future.getSession(); // Send the first ping message session.write(new TennisBall(10)); // Wait until the match ends. session.getCloseFuture().awaitUninterruptibly(); acceptor.unbind();