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

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


package com.gateway.connector.tcp.server;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.concurrent.ExecutorService;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gateway.connector.proto.Format;
import com.gateway.connector.proto.Proto;
import com.gateway.connector.utils.Consts;
import com.gateway.connector.utils.NetUtils;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

@ChannelHandler.Sharable
public class TcpServerHandler extends SimpleChannelInboundHandler {
	private final Logger logger = LoggerFactory.getLogger(TcpServerHandler.class);
	private ConnectorManager tcpConnector;
	private ApiProxy apiProxy;
	private ExecutorService executorService =null;

	public TcpServerHandler(ApiProxy apiProxy) {
		this.apiProxy = apiProxy;
		this.executorService=apiProxy.getExecutorService();
		tcpConnector = apiProxy.getConnectorManager();
	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) {
		ctx.flush();
	}

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, Proto msg) throws Exception {
		try {
			Runnable command = new Runnable() {
				@Override
				public void run() {
					SystemMessage sMsg = generateSystemMessage(ctx);
					// inbound
					Session session=tcpConnector.getSessionManager().getSession(msg.getSessionId());
					if(session!=null) {
						session.access();
					}
					if (msg.getFormat() == Format.REQUEST || msg.getFormat() == Format.SEND) {
						MessageWrapper wrapper = apiProxy.invoke(sMsg, msg);
						if (wrapper != null)
							receive(ctx, wrapper);
					}

				}
			};
			executorService.execute(command);
		} catch (Exception e) {
			logger.error("TcpServerHandler handler error.", e);
		}

	}

	public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
		logger.debug("TcpServerHandler Connected from {"
				+ NetUtils.channelToString(ctx.channel().remoteAddress(), ctx.channel().localAddress()) + "}");
	}

	public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
		logger.debug("TcpServerHandler Disconnected from {"
				+ NetUtils.channelToString(ctx.channel().remoteAddress(), ctx.channel().localAddress()) + "}");
	}

	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		super.channelActive(ctx);
		logger.debug("TcpServerHandler channelActive from (" + getRemoteAddress(ctx) + ")");
	}

	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		super.channelInactive(ctx);
		logger.debug("TcpServerHandler channelInactive from (" + getRemoteAddress(ctx) + ")");
		String sessionId0 = getChannelSessionHook(ctx);
		if (StringUtils.isNotBlank(sessionId0)) {
			tcpConnector.close(new MessageWrapper(MessageWrapper.MessageProtocol.CLOSE, sessionId0, null));
			logger.debug("TcpServerHandler channelInactive, close channel sessionId0 -> " + sessionId0 + ", ctx -> "
					+ ctx.toString());
		}
	}

	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		logger.debug(
				"TcpServerHandler (" + getRemoteAddress(ctx) + ") -> Unexpected exception from downstream." + cause);
		channelInactive(ctx);
	}

	private String getChannelSessionHook(ChannelHandlerContext ctx) {
		return ctx.channel().attr(Consts.SERVER_SESSION_HOOK).get();
	}

	private void setChannelSessionHook(ChannelHandlerContext ctx, String sessionId) {
		ctx.channel().attr(Consts.SERVER_SESSION_HOOK).set(sessionId);
	}

	/**
	 * to send client and receive the message
	 *
	 * @param ctx
	 * @param wrapper
	 */
	private void receive(ChannelHandlerContext ctx, MessageWrapper wrapper) {
		if (wrapper.isConnect()) {
			isConnect0(ctx, wrapper);
		} else if (wrapper.isClose()) {
			tcpConnector.close(wrapper);
		} else if (wrapper.isHeartbeat()) {
			tcpConnector.heartbeatClient(wrapper);
		} else if (wrapper.isRequest()) {
			tcpConnector.responseSendMessage(wrapper);
		} else if (wrapper.isNoKeepAliveMessage()) {
			tcpConnector.responseNoKeepAliveMessage(ctx, wrapper);
		} else if (wrapper.isReply()) {
			tcpConnector.responseSendMessage(wrapper);
		}
	}

	private void isConnect0(ChannelHandlerContext ctx, MessageWrapper wrapper) {
		String sessionId = wrapper.getSessionId();
		String sessionId0 = getChannelSessionHook(ctx);
		if (sessionId.equals(sessionId0)) {
			logger.debug("tcpConnector reconnect sessionId -> " + sessionId + ", ctx -> " + ctx.toString());
			tcpConnector.responseSendMessage(wrapper);
		} else {
			logger.debug("tcpConnector connect sessionId -> " + sessionId + ", sessionId0 -> " + sessionId0
					+ ", ctx -> " + ctx.toString());
			tcpConnector.connect(ctx, wrapper);
			setChannelSessionHook(ctx, sessionId);
			logger.debug("create channel attr sessionId " + sessionId + " successful, ctx -> " + ctx.toString());
		}
	}

	private SystemMessage generateSystemMessage(ChannelHandlerContext ctx) {
		SystemMessage systemMessage = new SystemMessage();
		systemMessage.setRemoteAddress(getRemoteAddress(ctx));
		systemMessage.setLocalAddress(getLocalAddress(ctx));

		return systemMessage;
	}

	private String getRemoteAddress(ChannelHandlerContext ctx) {
		SocketAddress remote1 = ctx.channel().remoteAddress();
		InetSocketAddress remote = (InetSocketAddress) remote1;
		return NetUtils.toAddressString(remote);
	}

	private String getLocalAddress(ChannelHandlerContext ctx) {
		SocketAddress local1 = ctx.channel().localAddress();
		InetSocketAddress local = (InetSocketAddress) local1;
		return NetUtils.toAddressString(local);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy