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

cn.tom.protocol.co.TMessageAdaptor Maven / Gradle / Ivy

The newest version!
package cn.tom.protocol.co;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import cn.tom.kit.IoBuffer;
import cn.tom.transport.IoAdaptor;
import cn.tom.transport.Messager.MessageCallback;
import cn.tom.transport.Messager.MessageHandler;
import cn.tom.transport.Session;
import cn.tom.transport.Ticket;
import cn.tom.transport.TicketManager;

public class TMessageAdaptor extends IoAdaptor {

	protected Map> handlerMap = new ConcurrentHashMap>();
	


	public TMessageAdaptor() {
	}

	@Override
	public TMessage decode(IoBuffer buf, Session session) {
		if (buf.remaining() < 5) return null;
		buf.markReadIndex();
		if (buf.readByte() != (byte) 0xff) { // 0xff 头标识符
			try {
				session.close();
				return null;
			} catch (Exception e) {
				// ignore
			}
		}
		int len = buf.readInt(); // 4
		if (buf.remaining() < len) {
			buf.resetReadIndex();
			return null;
		}
		buf.resetReadIndex();
		TMessage msg = new TMessage();
		msg.deserialize(buf);
		return msg;
	}

	@Override
	public IoBuffer encode(TMessage msg, Session session) {
		msg.serialize();
		return msg.toBytes();
	}

	@Override
	public void onMessage(TMessage msg, Session sess) throws IOException {
		TMessage tmsg = (TMessage) msg;
		int ask = tmsg.getHeader().getAsk();
		if (ask == 1) {
			// 先验证是否有Ticket处理
			if (msg.getMsgId() == null || msg.getMsgId().isEmpty()) {
				return;
			}
			Ticket ticket = removeTicket(msg.getMsgId());
			if (ticket != null) { // 此种情况为 ResultCallback 为null
				ticket.notifyResponse(msg);
				return;
			}
		}

		String module = findHandlerKey(tmsg);
		if (module == null) {
			msg.getHeader().setAsk((byte) 1);
			msg.setFieldSize(0);
			sess.write(msg);
			return;
		}

		if (sess.isServer()) {
			MessageHandler handler = handlerMap.get(module);
			if (handler != null) {
				handler.handleMessage(tmsg, sess);
				return;
			}
		}
	}

	@Override
	public Ticket createTicket(TMessage req, long timeout, MessageCallback callback) {
		return TicketManager.get().createTicket(req, timeout, callback);
	}

	@Override
	public Ticket removeTicket(String id) {
		return TicketManager.get().removeTicket(id);
	}

	@Override
	public void heartbeat(final Session sess) {
		if (sess.isServer()) return;

		synchronized (obj) {
			if (heartService == null || heartService.isShutdown()) {
				heartService = new ScheduledThreadPoolExecutor(1);
			}
		}
		heartService.scheduleAtFixedRate(new Runnable() {
			public void run() {
				try {
					TicketManager.get().prune(); // 回收内存
					TMessage msg = new TMessage(0, 0);
					msg.getHeader().setMethod("heartbeat".getBytes());
					sess.write(msg);
				} catch (Exception e) {
					// ignore
				}
			}
		},  6,  60*6, TimeUnit.SECONDS); // 60s *6

	}

	public void registerHandler(String command, MessageHandler handler) {
		this.handlerMap.put(command, handler);
	}

	{
		this.registerHandler("heartbeat", new MessageHandler() {
			public void handleMessage(TMessage msg, Session sess) throws IOException {
				// ignore
				log.debug("HEARTBEAT::" + sess.id());
			}
		});
	}

	public String findHandlerKey(TMessage msg) {
		String module = new String(msg.getHeader().getMethod());

		return module;
	}

	private ScheduledThreadPoolExecutor heartService = null;
	private Object obj = new Object();
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy