Apache Mina通信框架架构与应用

简介:
Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于 TCP/IP、UDP/IP协议栈的通信框架(当然,也可以提供 JAVA 对象的序列化服务、虚拟机管道通信服务等),Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用,Mina 提供了事件驱动、异步(Mina 的异步 IO 默认使用的是 JAVA NIO 作为底层支持)操作的编程模型。
从官网文档“MINA based Application Architecture”中可以看到Mina作为一个通信层框架,在实际应用所处的位置,如图所示:07ac68885a26e389144b7de5b4592295ee4837b6

Mina位于用户应用程序和底层Java网络API(和in-VM通信)之间,我们开发基于Mina的网络应用程序,就无需关心复杂的通信细节。

应用整体架构

再看一下,Mina提供的基本组件,如图所示:

826d7f43caf9732a3bd2c1d3bd69b6338fc4ce14

也就是说,无论是客户端还是服务端,使用Mina框架实现通信的逻辑分层在概念上统一的,即包含如下三层:

  • I/O Service – Performs actual I/O
  • I/O Filter Chain – Filters/Transforms bytes into desired Data Structures and vice-versa
  • I/O Handler – Here resides the actual business logic

想要开发基于MIna的应用程序,你只需要做如下事情:

  • Create an I/O service – Choose from already available Services (*Acceptor) or create your own
  • Create a Filter Chain – Choose from already existing Filters or create a custom Filter for transforming request/response
  • Create an I/O Handler – Write business logic, on handling different messages

下面看一下使用Mina的应用程序,在服务器端和客户端的架构细节:

服务器端架构
服务器端监听指定端口上到来的请求,对这些请求经过处理后,回复响应。它也会创建并处理一个链接过来的客户会话对象(Session)。服务器端架构如图所示:

a9a0511b8b6c55b1d8fa867590d3469a5394900a

对服务器端的说明,引用官网文档,如下所示:

  • IOAcceptor listens on the network for incoming connections/packets
  • For a new connection, a new session is created and all subsequent request from IP Address/Port combination are handled in that Session
  • All packets received for a Session, traverses the Filter Chain as specified in the diagram. Filters can be used to modify the content of packets (like converting to Objects, adding/removing information etc). For converting to/from raw bytes to High Level Objects, PacketEncoder/Decoder are particularly useful
  • Finally the packet or converted object lands in IOHandler. IOHandlers can be used to fulfill business needs.

客户端架构
客户端主要做了如下工作:

  • 连接到服务器端
  • 向服务器发送消息
  • 等待服务器端响应,并处理响应

客户端架构,如图所示:

2032f08349d690dd5867239bc9601e88db852b6e

对客户端架构的说明,引用官网文档内容,如下所示:

  • Client first creates an IOConnector (MINA Construct for connecting to Socket), initiates a bind with Server
  • Upon Connection creation, a Session is created and is associated with Connection
  • Application/Client writes to the Session, resulting in data being sent to Server, after traversing the Filter Chain
  • All the responses/messages received from Server are traverses the Filter Chain and lands at IOHandler, for processing

应用实例开发

下面根据上面给出的架构设计描述,看一下Mina(版本2.0.7)自带的例子,如何实现一个简单的C/S通信的程序,非常容易。
服务端
首先,服务器端需要使用的组件有IoAdaptor、IoHandler、IoFilter,其中IoFilter可选.
我们基于Mina自带的例子进行了简单地修改,实现服务端IoHandler的代码如下所示:

01 package org.shirdrn.mina.server;
02
03 import org.apache.mina.core.service.IoHandlerAdapter;
04 import org.apache.mina.core.session.IdleStatus;
05 import org.apache.mina.core.session.IoSession;
06 import org.slf4j.Logger;
07 import org.slf4j.LoggerFactory;
08
09 public class TinyServerProtocolHandler extends IoHandlerAdapter {
10 private final static Logger LOGGER = LoggerFactory.getLogger(TinyServerProtocolHandler.class);
11
12 @Override
13 public void sessionCreated(IoSession session) {
14 session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
15 }
16
17 @Override
18 public void sessionClosed(IoSession session) throws Exception {
19 LOGGER.info("CLOSED");
20 }
21
22 @Override
23 public void sessionOpened(IoSession session) throws Exception {
24 LOGGER.info("OPENED");
25 }
26
27 @Override
28 public void sessionIdle(IoSession session, IdleStatus status) {
29 LOGGER.info("*** IDLE #" + session.getIdleCount(IdleStatus.BOTH_IDLE) + " ***");
30 }
31
32 @Override
33 public void exceptionCaught(IoSession session, Throwable cause) {
34 session.close(true);
35 }
36
37 @Override
38 public void messageReceived(IoSession session, Object message)
39 throws Exception {
40 LOGGER.info( "Received : " + message );
41 if(!session.isConnected()) {
42 session.close(true);
43 }
44 }
45 }

这个版本中,IoHandlerAdapter实现了IoHandler接口,里面封装了一组用于事件处理的空方法,其中包含服务端和客户端的事件。在实际应用中,客户端可以选择客户端具有的事件,服务器端选择服务器端具有的事件,然后分别对这两类事件进行处理(有重叠的事件,如连接事件、关闭事件、异常事件等)。
客户端的IoHandler的具体实现也是类似的,不过多累述。
下面看启动服务器的主方法类,代码如下所示:

01 package org.shirdrn.mina.server;
02
03 import java.net.InetSocketAddress;
04
05 import org.apache.mina.filter.codec.ProtocolCodecFilter;
06 import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
07 import org.apache.mina.transport.socket.SocketAcceptor;
08 import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
09 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
11
12 public class TinyMinaServer {
13
14 private final static Logger LOG = LoggerFactory.getLogger(TinyMinaServer.class);
15 /** Choose your favorite port number. */
16 private static final int PORT = 8080;
17
18 public static void main(String[] args) throws Exception {
19 SocketAcceptor acceptor = new NioSocketAcceptor();
20 acceptor.setReuseAddress(true);
21 acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(newTextLineCodecFactory()));
22
23 // Bind
24 acceptor.setHandler(new TinyServerProtocolHandler());
25 acceptor.bind(new InetSocketAddress(PORT));
26 LOG.info("Listening on port " + PORT);
27
28 LOG.info("Server started!");
29
30 for (;;) {
31 LOG.info("R: " + acceptor.getStatistics().getReadBytesThroughput() + ", W: " + acceptor.getStatistics().getWrittenBytesThroughput());
32 Thread.sleep(3000);
33 }
34 }
35
36 }

客户端
实现客户端IoHandler的代码如下所示:

01 package org.shirdrn.mina.client;
02
03 import org.apache.mina.core.service.IoHandlerAdapter;
04 import org.apache.mina.core.session.IdleStatus;
05 import org.apache.mina.core.session.IoSession;
06 import org.slf4j.Logger;
07 import org.slf4j.LoggerFactory;
08
09 public class TinyClientProtocolHandler extends IoHandlerAdapter {
10
11 private final static Logger LOGGER = LoggerFactory
12 .getLogger(TinyClientProtocolHandler.class);
13
14 @Override
15 public void sessionCreated(IoSession session) {
16 LOGGER.info("CLIENT::CREATED");
17 }
18
19 @Override
20 public void sessionClosed(IoSession session) throws Exception {
21 LOGGER.info("CLIENT::CLOSED");
22 }
23
24 @Override
25 public void sessionOpened(IoSession session) throws Exception {
26 LOGGER.info("CLIENT::OPENED");
27 }
28
29 @Override
30 public void sessionIdle(IoSession session, IdleStatus status) {
31 LOGGER.info("CLIENT::*** IDLE #"
32 + session.getIdleCount(IdleStatus.BOTH_IDLE) + " ***");
33 }
34
35 @Override
36 public void exceptionCaught(IoSession session, Throwable cause) {
37 LOGGER.info("CLIENT::EXCEPTIONCAUGHT");
38 cause.printStackTrace();
39 }
40
41 public void messageSent(IoSession session, Object message) throws Exception {
42 LOGGER.info("CLIENT::MESSAGESENT: " + message);
43 }
44 }

下面看启动客户端的主方法类,代码如下所示:

01 package org.shirdrn.mina.client;
02
03 import java.net.InetSocketAddress;
04
05 import org.apache.mina.core.future.ConnectFuture;
06 import org.apache.mina.filter.codec.ProtocolCodecFilter;
07 import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
08 import org.apache.mina.transport.socket.SocketConnector;
09 import org.apache.mina.transport.socket.nio.NioSocketConnector;
10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory;
12
13 public class TinyMinaClient {
14
15 private final static Logger LOG = LoggerFactory.getLogger(TinyMinaClient.class);
16 /** Choose your favorite port number. */
17 private static final int PORT = 8080;
18
19 public static void main(String[] args) throws Exception {
20 SocketConnector connector = new NioSocketConnector();
21
22 // Connect
23 connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(newTextLineCodecFactory()));
24 connector.setHandler(new TinyClientProtocolHandler());
25
26 for (int i = 0; i < 10; i++) {
27 ConnectFuture future = connector.connect(new InetSocketAddress(PORT));
28 LOG.info("Connect to port " + PORT);
29 future.awaitUninterruptibly();
30 future.getSession().write(String.valueOf(i));
31 Thread.sleep(1500);
32 }
33
34 }
35 }

我们只是发送了十个数字,每发一次间隔1500ms。
测试上述服务器端与客户端交互,首先启动服务器端,监听8080端口。
接着启动客户端,连接到服务器端8080端口,然后发送消息,服务器端接收到消息后,直接将到客户端的连接关闭掉。

目录
相关文章
|
1天前
|
iOS开发 Python
mac:python安装路径,带你全面解析Python框架体系架构view篇
mac:python安装路径,带你全面解析Python框架体系架构view篇
|
1天前
|
Android开发
Android Jetpack架构开发组件化应用实战,字节跳动+阿里+华为+腾讯等大厂Android面试题
Android Jetpack架构开发组件化应用实战,字节跳动+阿里+华为+腾讯等大厂Android面试题
|
3天前
|
机器人 Unix C++
ROS机器人编程技术架构命令应用
ROS机器人编程技术架构命令应用
6 1
|
3天前
|
Cloud Native 安全 持续交付
构建未来:云原生架构在现代企业中的应用与挑战
【5月更文挑战第12天】 随着数字化转型的浪潮不断冲击传统IT架构,企业亟需灵活、高效且可扩展的技术解决方案以保持竞争力。云原生技术作为一种新兴的系统构建方式,以其独特的弹性、微服务和持续交付等特性,成为推动企业快速响应市场变化的关键因素。本文将深入探讨云原生架构的核心组件,分析其如何促进企业的敏捷性,以及在实施过程中可能遇到的挑战和解决策略,为企业采纳云原生技术提供参考。
|
3天前
|
Cloud Native Devops 持续交付
构建未来:云原生架构在现代企业中的应用与挑战
【5月更文挑战第11天】 随着数字化转型的深入,企业对技术的敏捷性、可扩展性和成本效益提出了更高的要求。云原生架构作为一种新兴的设计理念和实践方法,正逐渐成为推动企业技术革新的关键力量。本文将深入探讨云原生架构的核心组件,包括容器化、微服务、持续集成/持续交付(CI/CD)以及DevOps文化,并分析它们如何共同作用于企业的IT基础设施,实现灵活、高效的运营模式。同时,我们也将识别在采纳云原生技术时面临的主要挑战,并提出相应的解决策略,以帮助企业顺利过渡到云原生时代。
|
3天前
|
弹性计算 负载均衡 容灾
应用阿里云弹性计算:打造高可用性云服务器ECS架构
阿里云弹性计算助力构建高可用云服务器ECS架构,通过实例分布、负载均衡、弹性IP、数据备份及多可用区部署,确保业务连续稳定。自动容错和迁移功能进一步增强容灾能力,提供全方位高可用保障。
70 0
|
3天前
|
运维 Cloud Native 持续交付
构建未来:云原生架构在现代企业中的应用与挑战
【5月更文挑战第9天】 随着数字化转型的浪潮席卷全球,企业正迅速采纳云原生技术以实现敏捷性、可扩展性和弹性。本文深入探讨了云原生架构的关键组件,包括容器化、微服务、持续集成/持续部署(CI/CD)和DevOps文化,并分析了这些技术如何帮助企业加速产品上市时间,提高运营效率,并最终实现业务目标。同时,文章也识别了企业在采纳云原生实践中可能面临的挑战,如安全性考量、团队技能提升和复杂的网络管理,并提出了相应的解决方案和最佳实践。
|
3天前
|
分布式计算 Java Go
Golang深入浅出之-Go语言中的分布式计算框架Apache Beam
【5月更文挑战第6天】Apache Beam是一个统一的编程模型,适用于批处理和流处理,主要支持Java和Python,但也提供实验性的Go SDK。Go SDK的基本概念包括`PTransform`、`PCollection`和`Pipeline`。在使用中,需注意类型转换、窗口和触发器配置、资源管理和错误处理。尽管Go SDK文档有限,生态系统尚不成熟,且性能可能不高,但它仍为分布式计算提供了可移植的解决方案。通过理解和掌握Beam模型,开发者能编写高效的数据处理程序。
140 1
|
3天前
|
监控 负载均衡 API
微服务架构在现代企业中的应用与挑战
微服务架构已成为现代企业构建灵活且可扩展软件系统的首选。然而,随着其应用的普及,企业也面临着一系列新的挑战。本篇文章将探讨微服务架构的优势、实施时遇到的问题以及解决这些问题的策略。
|
3天前
|
Kubernetes Cloud Native 持续交付
构建高效云原生应用:Kubernetes与微服务架构的融合
【5月更文挑战第6天】 在数字化转型的浪潮中,企业正迅速采纳云原生技术以实现敏捷性、可扩展性和弹性。本文深入探讨了如何利用Kubernetes这一领先的容器编排平台,结合微服务架构,构建和维护高效、可伸缩的云原生应用。通过分析现代软件设计原则和最佳实践,我们提出了一个综合指南,旨在帮助开发者和系统架构师优化云资源配置,提高部署流程的自动化水平,并确保系统的高可用性。
32 1

推荐镜像

更多