从上一章分析的callNextMessageReceived函数中得知,mina框架会调用注册进的filter对客户端请求进行处理,默认的filter有HeadFilter和TailFilter,本章就分析mina源码中提供的ExecutorFilter和ProtocolCodecFilter。
直接看它的messageReceived函数,
public final void messageReceived(NextFilter nextFilter, IoSession session, Object message) {
if (eventTypes.contains(IoEventType.MESSAGE_RECEIVED)) {
IoFilterEvent event = new IoFilterEvent(nextFilter, IoEventType.MESSAGE_RECEIVED, session, message);
fireEvent(event);
} else {
nextFilter.messageReceived(session, message);
}
}
这里创建了一个IoFilterEvent并调用fireEvent,
protected void fireEvent(IoFilterEvent event) {
executor.execute(event);
}
executor是在ExecutorFilter构造函数中创建的OrderedThreadPoolExecutor,
public void execute(Runnable task) {
IoEvent event = (IoEvent) task;
IoSession session = event.getSession();
SessionTasksQueue sessionTasksQueue = getSessionTasksQueue(session);
Queue tasksQueue = sessionTasksQueue.tasksQueue;
boolean offerSession;
boolean offerEvent = eventQueueHandler.accept(this, event);
if (offerEvent) {
synchronized (tasksQueue) {
tasksQueue.offer(event);
if (sessionTasksQueue.processingCompleted) {
sessionTasksQueue.processingCompleted = false;
offerSession = true;
} else {
offerSession = false;
}
}
} else {
offerSession = false;
}
if (offerSession) {
waitingSessions.offer(session);
}
addWorkerIfNecessary();
if (offerEvent) {
eventQueueHandler.offered(this, event);
}
}
getSession返回的是一个NioSocketSession,getSessionTasksQueue返回的是该Session的任务队列,定义在OrderedThreadPoolExecutor中,
private SessionTasksQueue getSessionTasksQueue(IoSession session) {
SessionTasksQueue queue = (SessionTasksQueue) session.getAttribute(TASKS_QUEUE);
if (queue == null) {
queue = new SessionTasksQueue();
SessionTasksQueue oldQueue = (SessionTasksQueue) session.setAttributeIfAbsent(TASKS_QUEUE, queue);
if (oldQueue != null) {
queue = oldQueue;
}
}
return queue;
}
这里会创建SessionTasksQueue并添加进session中。
回到execute函数中,eventQueueHandler默认为IoEventQueueHandler.NOOP即IoEventQueueHandler,其accept函数直接返回true,因此接下来把刚才的event添加到任务队列中。因为是刚刚添加的task,因此肯定没有被处理,于是将processingCompleted设置为false,并把刚刚的session添加到waitingSessions中,等待被处理。然后就调用addWorkerIfNecessary添加线程处理刚刚添加的task,
private void addWorkerIfNecessary() {
if (idleWorkers.get() == 0) {
synchronized (workers) {
if (workers.isEmpty() || (idleWorkers.get() == 0)) {
addWorker();
}
}
}
}
如果没有Worker或者所有的Worker都在处理请求中,就调用addWorker创建线程进行处理,
private void addWorker() {
synchronized (workers) {
if (workers.size() >= super.getMaximumPoolSize()) {
return;
}
Worker worker = new Worker();
Thread thread = getThreadFactory().newThread(worker);
idleWorkers.incrementAndGet();
thread.start();
workers.add(worker);
if (workers.size() > largestPoolSize) {
largestPoolSize = workers.size();
}
}
}
Worker的总数量是有限制的,然后就创建Worker,启动线程进行处理,
public void run() {
thread = Thread.currentThread();
try {
for (;;) {
IoSession session = fetchSession();
idleWorkers.decrementAndGet();
try {
runTasks(getSessionTasksQueue(session));
} finally {
idleWorkers.incrementAndGet();
}
}
} finally {
}
}
}
fetchSession从waitingSessions中获取刚刚添加的NioSocketSession,然后更新空闲Worker方面的信息,接着就调用runTasks处理该Session中的任务队列。
private void runTasks(SessionTasksQueue sessionTasksQueue) {
for (;;) {
Runnable task;
Queue tasksQueue = sessionTasksQueue.tasksQueue;
synchronized (tasksQueue) {
task = tasksQueue.poll();
if (task == null) {
sessionTasksQueue.processingCompleted = true;
break;
}
}
eventQueueHandler.polled(OrderedThreadPoolExecutor.this, (IoEvent) task);
runTask(task);
}
}
这里就是从任务队列中依次取出任务,然后调用runTask进行处理,如果没有任务可以处理了,就将processingCompleted标志位设为true并退出循环。runTask定义在OrderedThreadPoolExecutor中,
private void runTask(Runnable task) {
beforeExecute(thread, task);
boolean ran = false;
try {
task.run();
ran = true;
afterExecute(task, null);
} catch (RuntimeException e) {
if (!ran) {
afterExecute(task, e);
}
throw e;
}
}
该函数就是执行task的run函数,在执行前后调用beforeExecute和afterExecute,这两函数用于重载,mina框架并未定义。任务的run函数定义在IoFilterEvent中,
public void run() {
fire();
}
fire函数如下,
public void fire() {
IoSession session = getSession();
NextFilter nextFilter = getNextFilter();
IoEventType type = getType();
switch (type) {
case MESSAGE_RECEIVED:
Object parameter = getParameter();
nextFilter.messageReceived(session, parameter);
break;
case MESSAGE_SENT:
WriteRequest writeRequest = (WriteRequest) getParameter();
nextFilter.messageSent(session, writeRequest);
break;
case WRITE:
writeRequest = (WriteRequest) getParameter();
nextFilter.filterWrite(session, writeRequest);
break;
case CLOSE:
nextFilter.filterClose(session);
break;
case EXCEPTION_CAUGHT:
Throwable throwable = (Throwable) getParameter();
nextFilter.exceptionCaught(session, throwable);
break;
case SESSION_IDLE:
nextFilter.sessionIdle(session, (IdleStatus) getParameter());
break;
case SESSION_OPENED:
nextFilter.sessionOpened(session);
break;
case SESSION_CREATED:
nextFilter.sessionCreated(session);
break;
case SESSION_CLOSED:
nextFilter.sessionClosed(session);
break;
default:
throw new IllegalArgumentException("Unknown event type: " + type);
}
}
回顾前面的代码,从上层传入的事件是一个MESSAGE_RECEIVED,因此这里首先调用getParameter获得客户端的请求消息,然后直接调用下一个过滤器进行处理。从这里也可以看出,ExecutorFilter其实没有做什么实质性的事情,就是根据传入的事件类型,调用下一个过滤器的不同处理函数进行处理,相当于一个事件的分发器。
ProtocolCodecFilter用于对客户端的请求进行解码,直接看它的messageReceived函数,
public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {
IoBuffer in = (IoBuffer) message;
ProtocolDecoder decoder = factory.getDecoder(session);
ProtocolDecoderOutput decoderOut = getDecoderOut(session, nextFilter);
while (in.hasRemaining()) {
int oldPos = in.position();
try {
lock.acquire();
decoder.decode(session, in, decoderOut);
decoderOut.flush(nextFilter, session);
} catch (Exception e) {
} finally {
}
}
}
这里factory假设为TextLineCodecFactory,其构造函数如下,
public TextLineCodecFactory(Charset charset) {
encoder = new TextLineEncoder(charset, LineDelimiter.UNIX);
decoder = new TextLineDecoder(charset, LineDelimiter.AUTO);
}
因此其getDecoder函数返回TextLineDecoder。
回到messageReceived中,getDecoderOut默认获得ProtocolDecoderOutputImpl,接下来调用TextLineDecoder的decode函数将数据解析到ProtocolDecoderOutputImpl的messageQueue中,再调用flush函数,flush函数只是简单地调用下一个过滤器进行处理。