java mina TcpLongSyncConnector 初始化

package com.pingan.emall.biz.communication.impl;




import com.paic.pafa.app.biz.service.BusinessServiceException;
import com.pingan.emall.biz.communication.GateWayManager;
import com.pingan.emall.biz.communication.TcpConnector;
import com.pingan.emall.biz.communication.TcpSessionLock;
import com.pingan.emall.biz.communication.TcpSessionManager;
import com.pingan.emall.biz.communication.handler.FundTradeProtocolCodecFactory;
import com.pingan.emall.biz.communication.handler.TcpCommunicationHandler;
import com.pingan.emall.dto.MidRequestDTO;
import com.pingan.emall.dto.MidResponseDTO;
import java.net.SocketAddress;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import org.apache.log4j.Logger;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
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.NioSocketConnector;


/**
 * Tcp 同步长连接Connector, 接收多网关配置, 连接时随机抽取一个存活的网关创建
 * IoSession并返回会话序列号,  发送报文时传入会话序列号以绑定会话。
 * Tcp连接配置bothIdle为默然20s, 超时会关闭连接
 * 
 * 发送报文后当前线程会同步等待(新建一个Lock并睡眠, 等待接收线程唤起)返回报文, 超过20s没有返回则抛出异常
 * 
 * @author LICHAO844
 *
 */
public class TcpLongSyncConnector implements TcpConnector {


private static Logger LOG = Logger.getLogger(TcpLongSyncConnector.class);
private GateWayManager gateWayManager;
private TcpSessionManager sessionManager;
private Map<Object, TcpSessionLock> locks = new ConcurrentHashMap<Object, TcpSessionLock>();
private IoConnector connector;
private IoHandlerAdapter handler;


/**
* gateWays : ip1:port1|ip2:port2|ip3:port3 ...
* @param gateWays
*/
public TcpLongSyncConnector(String gateWays, int idle) {

//启动线程20秒刷新获取随即网关
// Init gate way manager and scaner
initGateWay(gateWays);

//创建mina  NioSocketConnector
connector = new NioSocketConnector();


//TcpSessionManager  TcpSession  辅助类
sessionManager = new TcpSessionManager();

//创建mina
handler = new TcpCommunicationHandler(sessionManager, locks);
//创建mina
connector.setHandler(handler);
//创建mina
connector.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, idle);
//创建mina
DefaultIoFilterChainBuilder filterChain = connector.getFilterChain();
filterChain.addLast("codec", new ProtocolCodecFilter(new FundTradeProtocolCodecFactory(Charset.forName("GBK"))));
// add single thread pool for handler processor
filterChain.addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));
}


private void initGateWay(String gateWays) {
gateWayManager = new GateWayManager(gateWays);
}

@Override
public Object connect() {
SocketAddress socketAddress = gateWayManager.getRandomGateWay();
ConnectFuture future = connector.connect(socketAddress);
// 等待异步操作完成
future.awaitUninterruptibly();
IoSession session = future.getSession();
Object sessionId = session.getId();
sessionManager.putSession(sessionId, session);

return sessionId;
}


@Override
public MidResponseDTO send(Object sessionId, MidRequestDTO request) throws Exception {
IoSession session = sessionManager.getSession(sessionId);


if (session == null) {
throw new IllegalArgumentException("IoSession with sessionId not created : " + sessionId);
}

TcpSessionLock lock = new TcpSessionLock(sessionId);
locks.put(sessionId, lock);
try {
synchronized (lock) {
WriteFuture future = session.write(request);
lock.wait(20 * 1000);
}
} catch (InterruptedException e) {
LOG.error("Exception happens when wait for socket response", e);
throw e;
} finally {
locks.remove(sessionId);
}


if (lock.getMessage() == null) {
throw new BusinessServiceException("No response returned from Mid server");
}
return (MidResponseDTO) lock.getMessage();
}


@Override
public void close(Object sessionId) {
sessionManager.closeSession(sessionId);
}

public void destroy() {
sessionManager.destroy();
gateWayManager.destroy();
}
}
发布了80 篇原创文章 · 获赞 0 · 访问量 3万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章