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();
}