openfire和客户端之间的通信,主要使用了阿帕奇的mina框架,mina主要基于JDK的NIO,做了很多的封装,开发者不必关心底层网络,mina为你完成了这些,你只需将你的精力集中在业务层。
openfire中使用mina的版本比较低,好像是1.7版本,现在最新的版本是2.0.7,下面就以最新版本2.0.7做简单介绍。
NioSocketAcceptor acceptor = new NioSocketAcceptor(); ---这个就是开启一个socket的服务器
acceptor.bind(new InetSocketAddress(18567));--绑定地址
acceptor.getFilterChain().addLast("log1", new LoggingFilter(getClass()));--增加拦截器
acceptor.setHandler(IoHandlerAdapter);--设置消息处理类
IoHandlerAdapter是一个抽象类,实现的IoHandler接口。
ioHandler:
public abstract interface IoHandler
{
public abstract void sessionCreated(IoSession paramIoSession)
throws Exception;
public abstract void sessionOpened(IoSession paramIoSession)
throws Exception;
public abstract void sessionClosed(IoSession paramIoSession)
throws Exception;
public abstract void sessionIdle(IoSession paramIoSession, IdleStatus paramIdleStatus)
throws Exception;
public abstract void exceptionCaught(IoSession paramIoSession, Throwable paramThrowable)
throws Exception;
public abstract void messageReceived(IoSession paramIoSession, Object paramObject)
throws Exception;
public abstract void messageSent(IoSession paramIoSession, Object paramObject)
throws Exception;
}
其运行流层是:
1.当客户端和服务端建立一个连接,会调用sessionCreated;
2.客户端向服务端发送数据,会调用sessionOpened------>messageReceived;
3.客户端和服务器之间的数据在messageReceived中获取。
4.当客户端闲置下来了,服务器会调用sessionIdle,这主要通过以下代码设置相关参数:
SocketSessionConfig scfg = acceptor.getSessionConfig();
cfg.setIdleTime(IdleStatus.BOTH_IDLE, 10);当10s钟没有进行读写操作就会调用sessionIdle方法。
IdleStatus有3个类型:READER_IDLE,WRITER_IDLE,BOTH_IDLE。READER_IDLE为读的空闲类型;WRITER_IDLE,写的空闲类型,BOTH_IDLE读写的空闲类型
在这个方法中,可以做检测服务端和客户端之间的连接是否中断,如果中断就做相关处理,比如把这个回话移除会话列表中。
5.当服务端要向客户端发送数据的时候,会调用messageSent。如服务端调用session.write(Object o);的时候,会调用此方法。
6.当客户端和服务端通信异常的时候,会调用exceptionCaught。这个地方一般需要做处理,比如关闭当前会话。
7.当关闭会话的时候会调用sessionClosed方法。一般在这个地方将会话列表中的会话移除。
8.服务端最重要的事情是:处理业务数据,建立拦截器。在通信同往往是以字节码的形式传送的,要识别对应的二进制,需要进行相关的处理。写相关的拦截器就能解决相关问题。
mina为我们已经提供了很多的拦截器,比如日志的:LoggingFilter,比如处理文本的:
dc.addLast("dec", new ProtocolCodecFilter(new TextLineCodecFactory(
Charset.forName("UTF-8"))));
这个将设置编码方式。
在 org.apache.mina.filter包中可以看到很多已经实现的过滤器。
对于过滤器自己实现。
实现接口ProtocolCodecFactory,在这个接口中需要显示加解码,加解码需要实现相关的接口ProtocolDecoder,ProtocolEncoder。
对于mina提供了传送对象的过滤器,如ObjectSerializationCodecFactory,相关对象需要序列化。
在通信中往往要设置自己的通信报文格式,现有的比较成熟的是XMPP提供的即时通信技术中就有相关介绍。
下面介绍客户端方面的:
IoConnector connector=new NioSocketConnector();--建立一个connection
SocketSessionConfig dcfg = (SocketSessionConfig) this.connector.getSessionConfig();--获取会话配置
ConnectFuture connFuture = this.connector.connect(new InetSocketAddress("localhost", 18567));--设置连接地址和端口
connFuture.awaitUninterruptibly();--等待建立连接
session = connFuture.getSession();--获取会话。
connector.setHandler(IOhandler o);客户端的IOhandler 和服务端的一样,在此就可以做和服务端的连接操作了。
只是对mina做了简单的介绍,更多请查阅其他资料。
此篇文章就到此,稍后会有更多关于openfire的个人解读。
联系方式(qq):851392159