上一篇博客 Apache MINA (3) NioSocketAcceptor初始化 了解了NioSocketAcceptor的初始化过程,完成了初始化,Acceptor线程被阻塞,处于等待客户端请求到达的状态,通过进一步研究源代码了解Mina处理请求的过程。
当有客户端的请求到达时selector.select()被唤醒
if (selected > 0) {
// We have some connection request, let's process
// them here.
processHandles(selectedHandles());
}
processHandles(selectedHandles())负责处理所有接收到的请求,首先调用了NioSocketAcceptor的accept方法,接受来自客户端的请求,并初始化一个NioSocketSession,并将SocketChannel绑定到NioSession中,指定了处理该NioSession的NioProcesser,IoServices,IoFilterChain等,最后执行
session.getProcessor().add(session);
把session交给SimpleIoProcessorPool处理。
上一篇博客中介绍了SimpleIoProcessorPool的初始化,他初始化了一个无界线程池this.executor = Executors.newCachedThreadPool();并定义了一个cpu+1个NioProcessor绑定到这个executor中,每个NioProcessor中初始化了一个Selector,提供Nio相关的具体实现,如select(),read(),write()等方法
SimpleIoProcessorPool的add(S session)方法首先指定一个处理session的NioProcessor;其中getProcessor(session),该方法会先从session的attributeMap中找有没有指定好的Processor,如果没有,根据sessionId和cpu+1取模取到一个NioProcessor放到attributeMap中。
processor = pool[Math.abs((int) session.getId()) % pool.length];
session.setAttributeIfAbsent(PROCESSOR, processor);
拿到对应的NioProcessor之后再执行NioPorcessor的add(S sission)方法,实现类是在其父类AbstractPollingIoProcessor中,session会被放到一个线程安全的队列newSessions中
private final Queue<S> newSessions = new ConcurrentLinkedQueue<S>();
然后启动processor,执行startupProcessor();
该方法初始化一个AbstractPollingIoProcessor的内部线程类Processor并放到executor中执行
executor.execute(new NamePreservingRunnable(processor, threadName));
processor开始执行,调用NioProcessor的select()方法,然后执行handleNewSessions(),处理newSessions队列中的session,执行addNow()方法,拿到session对应的SelectableChannel,设置为非阻塞的通道,注册通道为OP_READ,准备读取数据,同时为session构建filterChain,然后通知listeners激活创建事件,激活过滤器当前session创建和打开事件。
然后执行process()方法开始读取数据,初始化IoBuffer
IoBuffer buf = IoBuffer.allocate(bufferSize);
调用NioProcessor的read()方法从channel中读取数据到IoBuffer中,这里指定的默认读取方式是读到buffer满或者数据读完然后结束然后调用buf.flip();重置buffer的指针为初始化状态
然后调用责任链激活数据已经读取到
filterChain.fireMessageReceived(buf);
如果数据已经读完,会将当前session放到flushingSessions队列中。
filterChain负责将从chain中读取的byte数据转换成业务需要的数据,如对象,字符串等,从之前Hellow World的例子中看到,为这个责任链添加了一个按行读取数据的filter
chain.addLast("myChain", new ProtocolCodecFilter(new TextLineCodecFactory()));
构造方法中指定了按行处理的数据的encoder和decoder,如果没有读到换行,则将临时数据存到TextLineDecoder的内部类Context中,直到读到换行,将整行放到AbstractProtocolDecoderOutput的消息队列中,如果消息队列不为空,才将转换好的数据传递给下一个filter
Queue<Object> messageQueue = getMessageQueue();
while (!messageQueue.isEmpty()) {
nextFilter.messageReceived(session, messageQueue.poll());
}
这个时候消息进入到对应业务处理的IoHandler的实现类中去完成业务的相关操作,在之前的例子中创建了一个对应的实现类SimpleMinaServerHandler来处理
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
String str = (String)message;
// 打印客户端
System.out.println("receive client message : [ " + str +" ]");
// 回写消息给客户端
session.write(count.incrementAndGet());
}
然后再调用session的write方法将处理后的信息回写给客户端
初始化WriteRequest,交给filterChain,执行fireFilterWrite回写数据给客户端
小结:
以上过程描述了一次简单的客户端请求处理的过程,其核心过程如下:
服务端接到客户端的请求,在bind监听端口后,调用startupAcceptor()方法,接收线程Acceptor被唤醒,创建IoSession,构造IoFilter链,将构造好的IoSession提交给IoProcessor来处理。
SimpleIoProcessorPool初始化时创建了一个cpu+1个IoProcessor来负责处处理请求,按照取模的方式找到一个对应的IoProcessor来处理IoSession,IoSession被放到一个newSessions的队列中等待被处理,startupProcessor()唤醒IoProcessor,开始读取数据,通过IoFilter链进行转换处理,最终提供给IoHandlerAdapter处理请求。
借用网上一张经典的图片来描述这个过程:
接下来会再深入研究mina的线程模型。
- 大小: 59.3 KB
分享到:
相关推荐
Apache MINA(Multipurpose Infrastructure for Network Applications)是一个开源框架,主要设计用于简化网络应用程序的开发,尤其是基于TCP和UDP协议的应用。它提供了高度可扩展和高性能的非阻塞I/O模型,使得...
MINA 提供了一套高级的网络通信抽象层,简化了开发过程,特别是对于处理TCP/IP和UDP/IP协议栈的应用。MINA的核心概念是事件驱动和非阻塞I/O,这使得它在处理大量并发连接时表现出色。 在这个"Apache MINA2学习笔记...
客户端架构主要涉及连接服务器、发送请求和接收响应的过程。与服务器端类似,客户端也需要使用 I/O Service、Filter Chain 和 I/O Handler。客户端的关键活动包括: - **发起连接**:使用 `IoConnector` 发起连接...
Apache MINA是一个高性能、异步事件驱动的网络应用程序框架,主要设计用于简化开发服务器端的高性能网络应用。这个框架提供了一种抽象层,允许开发者使用相同的API处理多种不同的传输协议,如TCP/IP、UDP/IP以及SSL/...
Apache Mina的核心理念是提供一个简洁而高效的框架,用于处理I/O操作,如TCP/IP和UDP通信。Mina通过使用NIO(非阻塞I/O)技术,可以处理大量的并发连接,这在构建大规模、高并发的网络应用时非常有用。 在`...
"服务端"表明这个项目关注的是网络应用的服务器部分,负责接收和处理客户端的请求。 项目中的"sprin-mina"可能是项目源码或配置文件的目录,其中可能包含了以下关键部分: 1. **配置文件**:可能包含Spring的XML...
Acceptor负责接收并处理来自客户端的连接请求,而Connector则用于客户端发起连接到服务器。 **服务器端实现:** 1. **创建IoAcceptor:** 使用`NioSocketAcceptor`类创建一个Acceptor实例,这是Mina2处理TCP连接的...
4. **Service**:服务端的核心是IoAcceptor,它负责监听指定的端口,并创建IoSession处理新的连接请求。你可以定义一个IoHandler接口的实现类,来处理IoSession的事件,比如打开、关闭、消息接收等。 5. **Protocol...
首先,Apache Mina的核心是它的事件驱动模型,它允许开发者以非阻塞的方式处理I/O操作。这种模型在处理大量并发连接时效率很高,因为系统资源可以被有效地利用,而不会因为等待I/O操作完成而被浪费。 实例开始前,...
4. **服务端交互**:测试程序会发送请求到服务器并接收响应。这可能涉及创建自定义的请求和响应类,以及相应的方法来发送和解析这些消息。 5. **Maven 配置**:在 `pom.xml` 文件中,会声明 Apache MINA 作为依赖,...
在Mina中,开发者可以创建一个服务端来监听特定端口,并接收客户端的连接请求。一旦连接建立,Mina会通过事件模型来处理数据传输。服务端和客户端的交互通常涉及编码、解码、业务逻辑处理等步骤。例如,你可以创建一...
Apache Mina提供了一种灵活的方式来处理这两种连接方式。在Mina中,我们可以通过配置`SocketSession`来管理连接的生命周期。对于短连接,我们可以在传输完成后调用`closeNow()`方法来关闭连接;而对于长连接,我们...
Apache Mina简化了这一过程,它允许开发者专注于业务逻辑,而不是底层的网络编程细节。 Apache Mina的核心组件包括: 1. **IoSession**:这是Mina中的核心对象,代表一个网络连接。它管理着与特定远程端点的交互,...
在MINA中,log4j用于收集和输出框架运行过程中的调试信息、警告和错误,帮助开发者追踪和解决问题。 3. **slf4j-api-1.5.11.jar**:简单日志门面(SLF4J)是一个为各种日志框架提供一个抽象层的API,允许最终用户在...
**Apache Mina** 是一个高度灵活且强大的网络应用程序框架,它旨在简化高性能和高可靠性网络应用程序的开发过程。Mina 提供了一个抽象层,允许开发者通过 Java NIO 在多种传输层协议(如 TCP/IP 和 UDP/IP)之上构建...
当Mina接收到客户端请求或数据时,会触发相应的事件,开发者可以通过监听这些事件来执行相应的业务逻辑。同样,Flex中的事件模型也允许用户在用户交互或其他系统事件发生时执行代码。 5. **安全性**:在Mina和Flex...
总的来说,通过Apache Mina实现的多人聊天室项目,不仅展示了Mina如何处理网络通信,还涉及到并发编程、协议解析、过滤器链等多方面的技术知识。对于学习和理解网络编程以及Mina框架的工作原理,这是一个非常有价值...
4. IoHandler:该接口负责业务逻辑的编写,也就是处理数据接收和发送的地方。 以一个简单的TCPServer为例,使用Mina框架开发网络通信应用的步骤大致如下: 第一步:编写IoService。由于IoService既可以是服务端也...