Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.gateway.connector.tcp.client.GateWayApi Maven / Gradle / Ivy
package com.gateway.connector.tcp.client;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.gateway.connector.proto.Cmd;
import com.gateway.connector.proto.Format;
import com.gateway.connector.proto.Proto;
import com.gateway.connector.utils.Consts;
import com.gateway.connector.utils.ProtoUtils;
import com.gateway.connector.utils.SSLClient;
import com.gateway.connector.utils.TopicUtils;
public class GateWayApi {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private ConcurrentHashMap htRequest = new ConcurrentHashMap();
private void htRequestRemove(int seq, boolean isPrint) {
ProtoReq pr = htRequest.remove(seq);
if (pr != null && isPrint) {
Proto msg = pr.getReqProto();
byte[] body = msg.getBody();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String content = body != null ? new String(body) : "";
logger.warn("RequestRemove cmd:{},format:{},seq:{},sessionid:{},body:{},beginTime:{},timeOut:{}",
msg.getCmd(), msg.getFormat(), msg.getSeq(), msg.getSessionId(), content,
sdf.format(new Date(pr.getBeginTime())), pr.getTimeOut());
}
}
private ProtoReq htRequestGet(int seq) {
return htRequest.get(seq);
}
private void htRequestAdd(ProtoReq req) {
req.setBeginTime(System.currentTimeMillis());
htRequest.put(req.getReqProto().getSeq(), req);
}
private boolean reconnectFlag = true;
public boolean isReconnectFlag() {
return reconnectFlag;
}
public void setReconnectFlag(boolean reconnectFlag) {
this.reconnectFlag = reconnectFlag;
}
private ConcurrentHashMap>> topicHm = new ConcurrentHashMap>>();
private ConcurrentHashMap>> topicWildCardHm = new ConcurrentHashMap>>();
private ConcurrentHashMap reTopicHm = new ConcurrentHashMap();
private boolean isConnected;
private final String _loginTopic = "SYS.ATS.LOGIN";
private boolean isLogOut = false;
private boolean isGzip = false;
private ProxyInfo proxyInfo;
public ProxyInfo getProxyInfo() {
return proxyInfo;
}
public void setProxyInfo(ProxyInfo proxyInfo) {
this.proxyInfo = proxyInfo;
}
public boolean isGzip() {
return isGzip;
}
public void setGzip(boolean isGzip) {
this.isGzip = isGzip;
client.setGzip(isGzip);
}
public void setLogOut(boolean isLogOut) {
this.isLogOut = isLogOut;
}
public boolean isConnected() {
return isConnected;
}
private boolean isLogin;
public boolean isLogin() {
return isLogin;
}
private IEventListener eventlistener = null;
public IEventListener getEventlistener() {
return eventlistener;
}
public void setEventlistener(IEventListener eventlistener) {
this.eventlistener = eventlistener;
}
public class PRspCallBack {
public IRspCallBack rspCallBack;
public String serverName;
public String method;
public void onRspMessage(Proto proto) {
String result = null;
if (proto != null && proto.getBody() != null) {
try {
result = new String(proto.getBody(), "UTF-8");
} catch (UnsupportedEncodingException e) {
logger.error("", e);
}
}
if (rspCallBack != null) {
rspCallBack.onRspMessage(result);
}
logger.debug(String.format("response->%s[%s] content:%s", serverName, method, result));
}
}
private IClientListener listener = new IClientListener() {
@Override
public void onMessage(Proto msg) {
_sendHeartInterval = System.currentTimeMillis();
if (msg.getFormat() == Format.REPLY || msg.getCmd() == Cmd.CONNECT) {
ProtoReq req = htRequestGet(msg.getSeq());
if (req != null) {
htRequestRemove(msg.getSeq(), false);
req.setRspProto(msg);
if (req.isSyncFlag()) {
req.cnotify();
} else {
req.notifyRspCallBack();
}
} else {
byte[] body = msg.getBody();
String content = body != null ? new String(body) : "";
logger.warn("drop cmd:{},format:{},seq:{},sessionid:{},body:{}", msg.getCmd(), msg.getFormat(),
msg.getSeq(), msg.getSessionId(), content);
}
} else if (msg.getFormat() == Format.NOTIFY) {
byte[] body = msg.getBody();
if (body != null) {
HashMap hm = ProtoUtils.getNotify(body);
String topic = hm.get("topic") + "";
String content = hm.get("content") + "";
onMessage(topic, content);
// 适配强制登出操作
if (isLogOut && topic.equals(_loginTopic)) {
onEvent(IEventListener.CONNECTION_LOGOUT);
}
}
}
}
private void onMessage(String topic, String content) {
CopyOnWriteArraySet> cas = topicHm.get(topic);
if (cas != null) {
for (IMessage> iMessage : cas) {
long begin = System.currentTimeMillis();
iMessage.onMessage(topic, content);
long end = System.currentTimeMillis();
long ts = end - begin;
if (ts >= 100) {
logger.warn("onMessage 耗时:{}:{}:{}", topic, iMessage, ts);
}
}
}
for (Entry>> entry : topicWildCardHm.entrySet()) {
String stopic = entry.getKey();
cas = entry.getValue();
if (TopicUtils.matchTopic(stopic, topic)) {
for (IMessage> iMessage : cas) {
long begin = System.currentTimeMillis();
iMessage.onMessage(topic, content);
long end = System.currentTimeMillis();
long ts = end - begin;
if (ts >= 100) {
logger.warn("onMessage 耗时:{}:{}:{}", stopic, iMessage, ts);
}
}
}
}
}
@Override
public void onLoginResult(Proto proto) {
sid = proto.getSessionId();
if (!StringUtils.isEmpty(sid)) {
isLogin = true;
reSubscribe();
startHeartBeat();
onEvent(IEventListener.CONNECTION_LOGIN_SUCCESS);
}
}
@Override
public void onException(Throwable throwable) {
// onDisConnect();
}
@Override
public void onDisConnect() {
isConnected = false;
isLogin = false;
sid = "";
onEvent(IEventListener.CONNECTION_CLOSED);
}
@Override
public void onConnect() {
isConnected = true;
onEvent(IEventListener.CONNECTION_SUCCESS);
}
};
private Proto sendLogin() {
try {
ProtoReq req = ProtoUtils.generateConnect(sid, userName, pwd, _extendParamDic);
this.htRequestAdd(req);
client.sendMessage(req.getReqProto());
req.cwait(Consts.WaitTime);
htRequest.remove(req.getReqProto().getSeq());
return req.getRspProto();
} catch (Exception e) {
logger.error("sendLogin error.", e);
}
return null;
}
private TcpClient client = new TcpClient(listener);
private String sid = "";
private Thread hbThread;
private String userName;
private String pwd;
@SuppressWarnings("rawtypes")
private Map _extendParamDic = null;
public String connect(String host, int port, String userName, String pwd, boolean isencryption, int protocal,
@SuppressWarnings("rawtypes") Map... dic) {
String result = null;
this.userName = userName;
this.pwd = pwd;
if (dic != null && dic.length > 0) {
this._extendParamDic = dic[0];
}
client.setProxyInfo(getProxyInfo());
boolean flag = client.connect(host, port, protocal);
if (flag) {
Proto proto = sendLogin();
if (proto != null) {
if (proto.getBody() != null) {
try {
result = new String(proto.getBody(), "UTF-8");
} catch (UnsupportedEncodingException e) {
logger.error("connect error", e);
}
} else {
result = "";
}
}
}
return result;
}
/**
* 同步请求
*
* @param serverName 请求的服务名
* @param method 请求的方法
* @param content 请求参数
* @param clazz 返回结果对象
* @param waitTime 超时等待时间
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public T requestSync(String serverName, String method, String content, Class clazz, long... waitTime)
throws Exception {
T t = null;
long wtime = Consts.WaitTime;
if (waitTime != null && waitTime.length > 0) {
wtime = waitTime[0];
}
logger.debug(String.format("requestSync->%s[%s] content:%s", serverName, method, content));
Proto proto = requestSync(serverName, method, content, wtime);
if (proto != null && proto.getBody() != null) {
if (String.class.equals(clazz)) {
t = (T) new String(proto.getBody(), "UTF-8");
} else {
t = JSON.parseObject(proto.getBody(), clazz);
}
}
logger.debug(String.format("%s[%s]->response content:%s", serverName, method, content));
return t;
}
/**
* 带usid同步请求
*
* @param sid
* @param serverName
* @param method
* @param content
* @param clazz
* @param waitTime
* @param
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public T requestSync(String sid, String serverName, String method, String content, Class clazz,
long... waitTime) throws Exception {
T t = null;
long wtime = Consts.WaitTime;
if (waitTime != null && waitTime.length > 0) {
wtime = waitTime[0];
}
logger.debug(String.format("requestSync->%s[%s] content:%s", serverName, method, content));
Proto proto = requestSync(serverName, method, content, wtime, new String[] { sid });
if (proto != null && proto.getBody() != null) {
if (String.class.equals(clazz)) {
t = (T) new String(proto.getBody(), "UTF-8");
} else {
t = JSON.parseObject(proto.getBody(), clazz);
}
}
logger.debug(String.format("%s[%s]->response content:%s", serverName, method, content));
return t;
}
@SuppressWarnings("unchecked")
public T requestHttpSync(String url, String serverName, String method, String content, Class clazz)
throws Exception {
T t = null;
String str = requestHttp(url, serverName, method, content);
if (!StringUtils.isEmpty(str)) {
if (String.class.equals(clazz)) {
t = (T) str;
} else {
t = JSON.parseObject(str, clazz);
}
}
return t;
}
@SuppressWarnings({ "resource", "deprecation" })
private String requestHttp(String url, String serverName, String method, String content) throws Exception {
SSLClient httpclient = new SSLClient();
HttpPost httppost = new HttpPost(url);
HashMap hm = new HashMap();
hm.put("serverName", serverName);
hm.put("method", method);
hm.put("content", content);
String body = JSON.toJSONString(hm);
httppost.addHeader("sessionId", sid);
StringEntity entity = new StringEntity(body.toString(), "utf-8");// 解决中文乱码问题
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
httppost.setEntity(entity);
ResponseHandler responseHandler = new BasicResponseHandler();
String result = httpclient.execute(httppost, responseHandler);
httppost.releaseConnection();
httpclient.getConnectionManager().shutdown();
return result;
}
public void requestAsync(String serverName, String method, String content, long waitTime, IRspCallBack rspCallBack,
String... sid) throws Exception {
logger.debug("requestAsync->%s[%s] content:%s", serverName, method, content);
PRspCallBack pcb = new PRspCallBack();
pcb.serverName = serverName;
pcb.method = method;
pcb.rspCallBack = rspCallBack;
requestAsync(serverName, method, content, waitTime, pcb, sid);
}
private void requestAsync(String serverName, String method, String content, long waitTime, PRspCallBack rspCallBack,
String... sids) throws Exception {
if (isLogin()) {
String tsid = sid;
if (sids != null && sids.length > 0) {
tsid = sid + "=NOP=" + sids[0];
}
ProtoReq req = ProtoUtils.generateRequest(tsid, serverName, method, content);
req.setRspCallBack(rspCallBack);
req.setTimeOut(waitTime);
htRequestAdd(req);
client.sendMessage(req.getReqProto());
return;
}
if (rspCallBack != null) {
rspCallBack.onRspMessage(null);
}
}
private Proto requestSync(String serverName, String method, String content, long waitTime, String... sids)
throws Exception {
if (this.isLogin()) {
String tsid = sid;
if (sids != null && sids.length > 0) {
tsid = sid + "=NOP=" + sids[0];
}
ProtoReq req = ProtoUtils.generateRequest(tsid, serverName, method, content);
req.setTimeOut(waitTime);
htRequestAdd(req);
client.sendMessage(req.getReqProto());
if (!req.cwait(waitTime)) {
htRequestRemove(req.getReqProto().getSeq(), true);
logger.warn("seq:{} requestSync timeout", req.getReqProto().getSeq());
}
return req.getRspProto();
}
return null;
}
/**
* 连接状态码:连接中,连接成功,重连,关闭
*
* @param code
*/
private void onEvent(int code) {// 连接状态
if (eventlistener != null) {
eventlistener.onEvent(code);
}
}
private void reSubscribe() {
if (!StringUtils.isEmpty(sid)) {
Runnable target = new Runnable() {
@Override
public void run() {
for (Entry entry : reTopicHm.entrySet()) {
String topic = entry.getKey();
String serverName = entry.getValue();
try {
requestSync(serverName, "subscribe", topic, String.class);
} catch (Exception e) {
logger.error("reSubscribe error", e);
}
}
}
};
Thread t = new Thread(target);
t.setName("reSubscribe thread");
t.start();
}
}
/**
* 订阅实时消息
*
* @param topic 订阅topic,mq推送的topic
* @param message 回调消息接口
* @param clazz 消息对象
*/
public synchronized boolean subscribe(String serverName, String topic, final IMessage message,
final Class clazz) throws Exception {
boolean flag = false;
if (this.isLogin()) {
flag = true;
CopyOnWriteArraySet> cas = null;
boolean isWildcard = TopicUtils.isWildcard(topic);
if (!isWildcard) {
cas = topicHm.get(topic);
if (cas == null) {
cas = new CopyOnWriteArraySet>();
topicHm.put(topic, cas);
}
} else {
cas = topicWildCardHm.get(topic);
if (cas == null) {
cas = new CopyOnWriteArraySet>();
topicWildCardHm.put(topic, cas);
}
}
if (!cas.contains(message)) {
cas.add(message);
if (cas.size() == 1) {// 第一次订阅
String result = requestSync(serverName, "subscribe", topic, String.class);
if (!StringUtils.isEmpty(result)) {
reTopicHm.put(topic, serverName);
} else {
flag = false;
}
}
}
if (!flag) {
cas.remove(message);
}
}
return flag;
}
public synchronized boolean subscribe(String topic, final IMessage message, final Class clazz)
throws Exception {
return subscribe("gateway", topic, message, clazz);
}
/**
* 退订实时消息
*
* @param topics 退订topic
* @param message 退订回调接口
* @param clazz 消息对象
* @throws Exception
*/
public synchronized boolean unSubscribe(String topic, final IMessage message, final Class clazz)
throws Exception {
boolean flag = false;
CopyOnWriteArraySet> cas = null;
boolean isWildcard = TopicUtils.isWildcard(topic);
if (!isWildcard) {
cas = topicHm.get(topic);
} else {
cas = topicWildCardHm.get(topic);
}
if (cas != null) {
cas.remove(message);
}
if (cas != null && cas.size() <= 0) {// 没有订阅
reTopicHm.remove(topic);
topicHm.remove(topic);
topicWildCardHm.remove(topic);
String result = requestSync("gateway", "unsubscribe", topic, String.class);
if (!StringUtils.isEmpty(result)) {
flag = true;
}
}
return flag;
}
private void reConnect() {
if (reconnectFlag && !isConnected()) {
client.connect();
}
if (isConnected && !isLogin()) {
sendLogin();
}
}
private long _sendHeartInterval;
private void checkRequestAsyncTimeOut()// 异步请求超时处理
{
try {
List lt = new ArrayList();
for (Entry entry : htRequest.entrySet()) {
ProtoReq req = entry.getValue();
if (!req.isSyncFlag()) {
if ((System.currentTimeMillis() - req.getBeginTime()) >= req.getTimeOut()) {
lt.add(req);
}
}
}
for (ProtoReq req : lt) {
htRequestRemove(req.getReqProto().getSeq(), true);
logger.warn("seq:{} requestAsync timeout", req.getReqProto().getSeq());
req.notifyRspCallBack();
}
} catch (Exception e) {
logger.error("checkRequestAsyncTimeOut", e);
}
}
private Object lockObj = new Object();
private void startHeartBeat() {
synchronized (lockObj) {
if (hbThread == null || !hbThread.isAlive()) {
Runnable target = new Runnable() {
@Override
public void run() {
while (!client.isStop()) {
try {
if (!StringUtils.isEmpty(sid) && isLogin()) {
long interval = (System.currentTimeMillis() - _sendHeartInterval) / 1000;
if (interval > Consts.HeartInterval) {
client.sendMessage(ProtoUtils.generateHeartbeat(sid));
}
}
checkRequestAsyncTimeOut();
reConnect();
Thread.sleep(1000);
} catch (Exception e) {
}
}
}
};
hbThread = new Thread(target);
hbThread.setName("heartbeat thread");
hbThread.start();
}
}
}
public void disconnect() {
synchronized (this) {
reTopicHm.clear();
topicHm.clear();
topicWildCardHm.clear();
htRequest.clear();
if (client != null) {
reconnectFlag = false;
client.disConnect();
}
}
}
}