学习mina同步与异步网络通讯(二)——服务器端
2013-08-24 00:37
465 查看
写个服务器端,做测试。
服务器端与客户端最大的区别是使用IoAcceptor和IoHandler
核心代码:
查看一下SocketAcceptor的代码,继承自IoAcceptor~
几个接口,获取配置、IP端口等信息、是否暂停等。
在IoAcceptor中,有一个接口
将会话绑定到客户端与服务端。怎么绑定的,没找到啊。。。
补充:
跟踪一下服务器端的线程,
MINA一共三种线程。
第一类线程:NioSocketAcceptor 唯一。用于bind监听端口,bind一次创建一个。客户端发送请求时,将请求发送给第二类线程处理。
第二类线程:Nioprocessor 处理客户端请求。每个请求1个线程。满了等待。acceptor = new NioSocketAcceptor(4);创建最大4个线程。handler中的sessionCreated
第三类线程:处理业务逻辑的线程,使用过滤器添加。第二类线程接收请求后转给第三类请求处理。handler中的从sessionOpen到close。
如果不添加过滤器,那么业务处理将在第二类线程中完成。
acceptor = new NioSocketAcceptor(4);
//第三类线程
//acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));
使用可重用的线程池,当现有线程有可用则继续使用,如没有,创建新的线程。满了继续添加新的(PS:适合短连接。用完就销毁。提高性能啊!有机会测试一下。看最多能整多少个线程~)
newFixedThreadPool(int nThreads)
需要恶补一下线程方面的知识了~
服务器端与客户端最大的区别是使用IoAcceptor和IoHandler
核心代码:
package com.lele.test.mina.server.acceptor; import java.io.IOException; import java.net.InetSocketAddress; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.logging.LoggingFilter; import org.apache.mina.transport.socket.SocketAcceptor; import org.apache.mina.transport.socket.SocketSessionConfig; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; import com.lele.test.mina.server.acceptor.codec.CodecFactory; import com.lele.test.mina.server.acceptor.handle.MinaServerHandler; public class MinaAcceptor{ private int port = 1234; // socket接收器 private SocketAcceptor acceptor; private static MinaAcceptor minaAcceptor; private SocketSessionConfig sessionConfig; //单例模式 public static MinaAcceptor getInstances(){ if (null == minaAcceptor) { minaAcceptor = new MinaAcceptor(); } return minaAcceptor; } protected MinaAcceptor() { acceptor = new NioSocketAcceptor(); //此处的过滤器与客户端代码一样,使用自定义的CodecFactory acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new CodecFactory(false))); acceptor.getFilterChain().addLast("logger", new LoggingFilter()); sessionConfig = getAcceptor().getSessionConfig(); // 设置IoSession的read()方法为可用,默认为false,这行可以去掉,服务器端的read是被封装的,不需要定义IoSession,也不涉及到read(),应该是accptor内部实现了。 sessionConfig.setUseReadOperation(true); //设置处理器 acceptor.setHandler(new MinaServerHandler()); try { //注册端口。 acceptor.bind(new InetSocketAddress(port)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public SocketAcceptor getAcceptor() { return acceptor; } public void setAcceptor(SocketAcceptor acceptor) { this.acceptor = acceptor; } public SocketSessionConfig getSessionConfig() { return sessionConfig; } public void setSessionConfig(SocketSessionConfig sessionConfig) { this.sessionConfig = sessionConfig; } }handler:
package com.lele.test.mina.server.acceptor.handle; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.core.session.IoSession; import com.lele.test.mina.server.acceptor.pojo.ApplyKeyRequest; import com.lele.test.mina.server.acceptor.pojo.ApplyKeyResponse; public class MinaServerHandler extends IoHandlerAdapter { public void sessionCreated(IoSession session) throws Exception { // TODO Auto-generated method stub System.out.println("session is created!"); } public void sessionOpened(IoSession session) throws Exception { // TODO Auto-generated method stub System.out.println("session is Opened!"); } public void sessionClosed(IoSession session) throws Exception { // TODO Auto-generated method stub System.out.println("session is Closed!"); } public void sessionIdle(IoSession session, IdleStatus status) throws Exception { // TODO Auto-generated method stub } public void exceptionCaught(IoSession session, Throwable cause) throws Exception { // TODO Auto-generated method stub } public void messageReceived(IoSession session, Object message) throws Exception { if(message instanceof UserReq){ System.out.println(((UserRequest) message).getUsername()); } //准备返回的数据! UserRes a = new UserRes(); a.setSay("Mr.S say helloWorld!!!"); //此处与客户端的write一致,会调用filter进行转码,转成Byte[] session.write(a); } public void messageSent(IoSession session, Object message) throws Exception { // TODO Auto-generated method stub } }接收完数据后,会自动关闭session。创建SESSION与打开session都是自动完成的。只要注册了handle~
查看一下SocketAcceptor的代码,继承自IoAcceptor~
几个接口,获取配置、IP端口等信息、是否暂停等。
在IoAcceptor中,有一个接口
IoSession newSession(SocketAddress remoteAddress, SocketAddress localAddress);
将会话绑定到客户端与服务端。怎么绑定的,没找到啊。。。
public void messageReceived(IoSession session, Object message) throws Exception { if(message instanceof UserReq){ System.out.println(((UserRequest) message).getUsername()); } //准备返回的数据! UserRes a = new UserRes(); a.setSay("Mr.S say helloWorld!!!"); //此处与客户端的write一致,会调用filter进行转码,转成Byte[] session.write(a); }服务启动时加了过滤器,所以这面message读过来就已经解码成UserReq了
补充:
跟踪一下服务器端的线程,
MINA一共三种线程。
第一类线程:NioSocketAcceptor 唯一。用于bind监听端口,bind一次创建一个。客户端发送请求时,将请求发送给第二类线程处理。
第二类线程:Nioprocessor 处理客户端请求。每个请求1个线程。满了等待。acceptor = new NioSocketAcceptor(4);创建最大4个线程。handler中的sessionCreated
第三类线程:处理业务逻辑的线程,使用过滤器添加。第二类线程接收请求后转给第三类请求处理。handler中的从sessionOpen到close。
如果不添加过滤器,那么业务处理将在第二类线程中完成。
acceptor = new NioSocketAcceptor(4);
//第三类线程
//acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));
使用可重用的线程池,当现有线程有可用则继续使用,如没有,创建新的线程。满了继续添加新的(PS:适合短连接。用完就销毁。提高性能啊!有机会测试一下。看最多能整多少个线程~)
Executors.newCachedThreadPool()还有一种,创建固定个数的线程池,也是可重用的,只不过限制个数nThreads,满了会阻塞
newFixedThreadPool(int nThreads)
需要恶补一下线程方面的知识了~
相关文章推荐
- 学习mina同步与异步网络通讯(一)——同步通讯
- 网络传输之同步异步SOCKET通讯和多线程
- 网络编程学习_设计模式_半同步半异步模式
- 网络传输之同步异步SOCKET通讯和多线程[转]
- 网络通信之同步异步阻塞非阻塞
- 关于网络IO中的同步、异步、阻塞、非阻塞
- 网络IO之阻塞、非阻塞、同步、异步总结
- ios网络学习------3 用非代理方法实现异步post请求
- 异步串行通讯和同步串行通讯对比
- [学习笔记]Java网络编程之UDP通讯
- 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架
- 网络编程释疑之:同步,异步,阻塞,非阻塞
- [转载]在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(一)----基础类库部分 .
- IOS学习之——同步请求、异步请求、GET请求、POST请求
- NIO通讯框架之阿堂教程:Mina学习笔记-高级进阶篇(三)
- Node.js的学习历程二同步异步调用等基础知识的理解
- [学习笔记]Java网络编程之UDP通讯
- ReactNative 学习笔记 Component - ViewPager, 异步网络数据
- 网络编程中的异步、同步、阻塞、非阻塞
- zookeeper学习心得二:同步与异步