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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章