功能: Mina启动一个监听端口,接收来自A机器的请求,然后将请求处理以后发送给B机器,等待B的响应,在获取B的响应以后,处理B的响应,并将处理结果响应给A
通讯流程步骤:
1.初始化:
当Mina框架被初始化时,它会创建一个IoAcceptor对象,用于监听并接受来自客户端的连接请求
2.接收外部请求:
接收请求,封装成IOSession 对象,接着将IOSession 对象传递给过滤器处理
3.过滤器:
Mina的核心,过滤器按照一定的顺序来处理网络通信的请求和响应,例如处理网络数据的编码和解码、实现协议的解析和封装、处理网络事件等等
4.数据传输:
IOSession对象创建的时候,就开始有数据传输了
5.关闭连接
当一个IoSession对象被关闭时,Mina框架会依次调用所有的过滤器对象,以确保所有的资源被正确释放
涉及到:Mina的拦截器/多线程(必须有)/加解密工厂处理
具体逻辑为:
MainServer 类为服务监听,对应的请求加解密为insertdecoder/insertencoder。发送的对应是sendClient,对应的发送加解密为outdecoder/outencoder.
一个完整的流程为:
A的请求进来,先到insertdecoder,然后到messageReceived ,这里调用的转发,SendClient。SendClient 吸先创建连接,然后session.write 写出信息,写出的时候经过outencode修饰,然后收到B的响应,先调用outdecode方法处理信息,然后就回归到messageReceived ,接着到messageSent
具体代码如下
程序启动入口
EnterServer
public class EnterServer {
public static void main(String[] args){
new MainServer().startServer();
}
}
接收主方法 ,继承 IoHandlerAdapter
MainServer
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.future.ReadFuture;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class MainServer extends IoHandlerAdapter {
public void startServer(){
NioSocketAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast("thread-pool",new ExecutorFilter(newFixedThreadPool()));
acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter( new InsertCodecFactory()));
acceptor.setHandler(this);
try {
acceptor.bind(new InetSocketAddress(111));
} catch (IOException e) {
e.printStackTrace();
}
}
public void messageReceived(IoSession session, Object message) throws Exception {
System.out.println("messageReceived--------------");
System.out.println("信息开始进行业务处理,这里的message 是刚才过滤器处理的"+message.toString());
String ret = new SendClient().Mydeo(message.toString());
session.write(ret);
System.out.println("messageReceived--------------over");
}
public void messageSent(IoSession session, Object message) throws Exception {
System.out.println("messageSent--------------");
System.out.println("承接输出加密信息,开始写出信息");
super.messageSent(session,message);
}
private ExecutorService newFixedThreadPool(){
System.out.println("线程池,涉及两个线程的就需要,例如接收以后发送");
return new ThreadPoolExecutor(10,20,22222333,TimeUnit.MILLISECONDS,new LinkedBlockingDeque<Runnable>(6));
}
}
接收对应的加解密
InsertCodecFactory
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;
public class InsertCodecFactory implements ProtocolCodecFactory {
private ProtocolDecoder decoder;
private ProtocolEncoder encoder;
public InsertCodecFactory(){
decoder = new insertDecoder();
encoder = new insertEncoder();
}
@Override
public ProtocolEncoder getEncoder(IoSession ioSession) throws Exception {
return encoder;
}
@Override
public ProtocolDecoder getDecoder(IoSession ioSession) throws Exception {
return decoder;
}
}
insertDecoder
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
public class insertDecoder extends CumulativeProtocolDecoder {
@Override
protected boolean doDecode(IoSession ioSession, IoBuffer ioBuffer, ProtocolDecoderOutput protocolDecoderOutput) throws Exception {
System.out.print("InsertdoDecode -----------");
System.out.println("信息接入的解密方法,获取接入信息 ioBuffer,写出信息 protocolDecoderOutput");
int size = ioBuffer.remaining();
byte[] bytes = new byte[size];
ioBuffer.get(bytes,0,size);
String inputStr = new String(bytes);
String outputString = "doDecode ";
protocolDecoderOutput.write(outputString+inputStr);
return true;
}
}
insertEncoder
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import java.nio.charset.Charset;
public class insertEncoder extends ProtocolEncoderAdapter {
@Override
public void encode(IoSession ioSession, Object o, ProtocolEncoderOutput protocolEncoderOutput) throws Exception {
System.out.println("insertEncode--------------");
System.out.println("这里是响应加密的位置,进来是 Object o"+o.toString()+" 写出是out ");
String ret = "encode "+o.toString();
IoBuffer buffer = IoBuffer.allocate(1024);
buffer.setAutoExpand(true);
buffer.putString(ret, Charset.forName("GBK").newEncoder());
buffer.flip();
protocolEncoderOutput.write(buffer);
protocolEncoderOutput.flush();
buffer.free();
}
}
发送的主方法继承 IoHandlerAdapter
SendClient
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.future.ReadFuture;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;
public class SendClient extends IoHandlerAdapter {
//单独起一个
public String Mydeo(String nn){
IoSession session = null;
NioSocketConnector connector = new NioSocketConnector();
connector.setConnectTimeoutMillis(300000000);
connector.getFilterChain().addLast("codec",new ProtocolCodecFilter(new OutCodecFactory()));
SocketSessionConfig cfg =connector.getSessionConfig();
cfg.setReadBufferSize(1024<<2);
cfg.setSendBufferSize(1024<<2);
cfg.setUseReadOperation(true);
cfg.setSoLinger(2);
connector.setHandler(this);
ConnectFuture connectFuture = connector.connect(new InetSocketAddress("127.0.0.1",222));
connectFuture.awaitUninterruptibly();
if(connectFuture.isDone()&&connectFuture.isConnected()){
session = connectFuture.getSession();
}else {
connector.dispose();
connectFuture=null;
}
System.out.println("获取对外连接 Session 成--------");
session.write("转发信息--发出 session.write--------------------");
System.out.println("转发信息完成,准备接收响应--------");
System.out.println("发送后状态"+session.isActive());
ReadFuture readFuture = session.read();
if(readFuture.awaitUninterruptibly(420000000, TimeUnit.MICROSECONDS)){
System.out.println("------等待没有超时----------");
Object obj = readFuture.getMessage();
session.closeNow();//及时关闭
return obj.toString();
}else {
System.out.println("等待响应超时");
throw new RuntimeException();
}
}
}
发送对应的加解密
OutCodecFactory
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;
public class OutCodecFactory implements ProtocolCodecFactory {
private ProtocolDecoder decoder;
private ProtocolEncoder encoder;
public OutCodecFactory(){
decoder = new OutDecoder();
encoder = new OutEncoder();
}
@Override
public ProtocolEncoder getEncoder(IoSession ioSession) throws Exception {
return encoder;
}
@Override
public ProtocolDecoder getDecoder(IoSession ioSession) throws Exception {
return decoder;
}
}
OutDecoder
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import java.nio.charset.Charset;
public class OutDecoder extends CumulativeProtocolDecoder {
@Override
protected boolean doDecode(IoSession ioSession, IoBuffer ioBuffer, ProtocolDecoderOutput protocolDecoderOutput) throws Exception {
System.out.println("OutDecoder------------------------------");
int size = ioBuffer.remaining();
byte[] tmp = new byte[size];
ioBuffer.mark();
ioBuffer.get(tmp,0,size);
String tem = new String(tmp, Charset.forName("GBK"));
protocolDecoderOutput.write(tem);
return true;
}
}
OutEncoder
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import java.nio.charset.Charset;
public class OutEncoder extends ProtocolEncoderAdapter {
@Override
public void encode(IoSession ioSession, Object o, ProtocolEncoderOutput protocolEncoderOutput) throws Exception {
System.out.println("OutEncoder----------------");
System.out.println("数据输出前处理");
IoBuffer buffer = IoBuffer.allocate(256);
buffer.setAutoExpand(true);
buffer.putString((CharSequence) o, Charset.forName("GBK").newEncoder());
buffer.flip();
protocolEncoderOutput.write(buffer);
protocolEncoderOutput.flush();
buffer.free();
}
}