All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gateway.connector.tcp.server.AbstractApiProxy Maven / Gradle / Ivy

package com.gateway.connector.tcp.server;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.commons.lang3.StringUtils;
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.JsonUtils;
import com.gateway.connector.utils.ProtoUtils;
import com.gateway.connector.utils.TopicUtils;

/**
 * 服务端端接口
 * 
 * @author deshuai.kong
 *
 */
public abstract class AbstractApiProxy implements ApiProxy {
	protected final Logger logger = LoggerFactory.getLogger(AbstractApiProxy.class);
	private TopicManager topicManager = new TopicManager();
	protected ConnectorManager connectorManager = new ConnectorManager();
	protected ExecutorService executorService = Executors.newCachedThreadPool();;

	@Override
	public ExecutorService getExecutorService() {

		return executorService;
	}

	public AbstractApiProxy() {
		this.connectorManager.getSessionManager().sessionListeners.add(sessionListener);
	}

	SessionListener sessionListener = new SessionListener() {

		@Override
		public void sessionDestroyed(SessionEvent se) {
			topicManager.clear(se.getSession().getSessionId());
			logger.info("sessionDestroyed " + se.getSession().getUserName() + ":" + se.getSession().getSessionId());
		}

		@Override
		public void sessionCreated(SessionEvent se) {
			logger.info("sessionCreated " + se.getSession().getUserName() + ":" + se.getSession().getSessionId());
		}
	};

	public void addSessionListener(SessionListener sl) {
		this.connectorManager.getSessionManager().sessionListeners.add(sl);
	}

	public ConnectorManager getConnectorManager() {
		return connectorManager;
	}

	public MessageWrapper invoke(SystemMessage sMsg, Proto message) {
		byte[] body = message.getBody();
		String content = body != null ? new String(body) : "";
		logger.debug(String.format("cmd:%s,format:%s,seq:%s,sessionid:%s,body:%s", message.getCmd(),
				message.getFormat(), message.getSeq(), message.getSessionId(), content));

		if (message.getCmd() == Cmd.CONNECT) {

			MessageWrapper mw = OnLogin(sMsg, message);

			return mw;

		} else if (message.getCmd() == Cmd.HEARTBEAT) {
			return OnHeartBeat(sMsg, message);

		} else if (message.getCmd() == Cmd.SEND && message.getFormat() == Format.REQUEST) {

			Map hm = JsonUtils.Deserialize(body, Map.class);
			String serverName = hm.get("serverName") + "";
			String method = hm.get("method") + "";
			content = hm.get("content") + "";

			if ("subscribe".equals(method)) {// 订阅
				return OnSubscribe(sMsg, message, serverName, method, content);
			} else if ("unsubscribe".equals(method)) {
				return OnUnSubscribe(sMsg, message, content);
			} else {
				try {
					return OnRequestReply(sMsg, message, serverName, method, content);
				} catch (Exception e) {
					logger.error(e.getMessage());
					HashMap ehm = new HashMap<>();
					ehm.put("Code", "1003");
					ehm.put("Msg", e.getMessage() + "");
					byte[] resultValue = JsonUtils.SerializerBytes(ehm);
					message.setBody(resultValue);
					message.setFormat(Format.REPLY);
					return new MessageWrapper(MessageWrapper.MessageProtocol.REPLY, message.getSessionId(), message);
				}
			}
		}
		return null;
	}

	public MessageWrapper OnLogin(SystemMessage sMsg, Proto message) {
		String sessionId = message.getSessionId();
		byte[] body = message.getBody();
		String content = body != null ? new String(body) : "";
		if (StringUtils.isEmpty(sessionId)) {
			sessionId = UUID.randomUUID().toString();
			message.setSessionId(sessionId);
			message.setBody(content.getBytes());
		}
		@SuppressWarnings("unchecked")
		HashMap hm = JSON.parseObject(content, HashMap.class);
		String userName = hm.get("userName") + "";
		MessageWrapper mw = new MessageWrapper(MessageWrapper.MessageProtocol.CONNECT, sessionId, message);
		mw.setUserName(userName);
		return mw;
	}

	public MessageWrapper OnHeartBeat(SystemMessage sMsg, Proto message) {
		return new MessageWrapper(MessageWrapper.MessageProtocol.HEART_BEAT, message.getSessionId(), message);
	}

	public MessageWrapper OnSubscribe(SystemMessage sMsg, Proto message, String serverName, String method,
			String topic) {

		String sessionid = message.getSessionId();
		Session session = this.connectorManager.getSessionManager().getSession(sessionid);
		String userName = "";
		if (session != null) {
			userName = session.getUserName();
		}
		MessageWrapper mr = null;

		boolean flag = false;
		String code = "0000";
		String msg = "Success";
		if (!"gateway".equals(userName) && !"gateway".equals(serverName)) {
			mr = OnRequestReply(sMsg, message, serverName, topic, "");
			if (mr != null) {
				try {
					Proto proto = (Proto) mr.getBody();
					if (proto.getBody() != null) {
						HashMap rhm = JSON.parseObject(proto.getBody(), HashMap.class);
						if (rhm.containsKey("Code")) {
							code = rhm.get("Code") + "";
							if ("1005".equals(code)) {
								flag = true;
								msg = rhm.get("Msg") + "";
								logger.warn("{}:{},so can't subscribe: {}", code, msg, topic);
								code = "";
							}
						}
						if (!flag) {
							rhm.remove("SRL");
							for (Entry entry : rhm.entrySet()) {
								String topic1 = entry.getKey();
								String content1 = entry.getValue() + "";
								this.notify(sessionid, topic1, content1);
							}
						}
					}
				} catch (Exception e) {
					logger.error("{}", topic, e);
				}
			}

		}

		if (!flag) {
			topicManager.add(sessionid, topic);
		}
		message = ProtoUtils.generateReply(sessionid, message.getCmd(), message.getSeq(), code, msg);

		return new MessageWrapper(MessageWrapper.MessageProtocol.REPLY, message.getSessionId(), message);
	}

	public MessageWrapper OnUnSubscribe(SystemMessage sMsg, Proto message, String topic) {

		String sessionid = message.getSessionId();
		message = ProtoUtils.generateReplySuccess(sessionid, message.getCmd(), message.getSeq());
		topicManager.remove(sessionid, topic);
		return new MessageWrapper(MessageWrapper.MessageProtocol.REPLY, message.getSessionId(), message);

	}

	public abstract MessageWrapper OnRequestReply(SystemMessage sMsg, Proto message, String serverName, String method,
			String content);

	public List notify(String topic, String content) {
		logger.debug("notify1:{},{}", topic, content);
		List lt = new ArrayList();
		for (Entry> entry : topicManager.getTopics().entrySet()) {
			String sid = entry.getKey();
			CopyOnWriteArraySet cas = entry.getValue();
			if (cas.contains(topic)) {
				String userName = notify(sid, topic, content);
				if (userName != null) {
					lt.add(userName);
				}
			}
		}
		for (Entry> entry : topicManager.getTopicsWildCard().entrySet()) {
			String sid = entry.getKey();

			CopyOnWriteArraySet cas = entry.getValue();
			for (String stopic : cas) {
				if (TopicUtils.matchTopic(stopic, topic)) {
					String userName = notify(sid, topic, content);
					if (userName != null) {
						lt.add(userName);
					}
				}
			}
		}
		return lt;
	}

	private byte[] getBody(String topic, String content) {
		HashMap hm = new HashMap<>();
		hm.put("topic", topic);
		hm.put("content", content);
		byte[] body = JSON.toJSONBytes(hm);
		return body;
	}

	public String notify(String sid, String topic, String content) {
		String userName = null;
		byte[] body = getBody(topic, content);
		Proto proto = ProtoUtils.generateNotify(sid, body);
		try {
			if (connectorManager.exist(sid)) {
				userName = connectorManager.send(sid, proto);
				logger.debug("notify2:{},{},{},{}", sid, userName, topic, content);
			}
		} catch (Exception e) {
			logger.error("notify error", e);
		}
		return userName;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy