Mina 接收并转发信息

功能: 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();

    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值