package com.snowcattle.game.service.net.message.process;
import com.snowcattle.game.logic.net.NetMessageProcessLogic;
import com.snowcattle.game.common.IUpdatable;
import com.snowcattle.game.common.constant.GlobalConstants;
import com.snowcattle.game.common.constant.Loggers;
import com.snowcattle.game.common.exception.GameHandlerException;
import com.snowcattle.game.common.util.ErrorsUtil;
import com.snowcattle.game.manager.LocalMananger;
import com.snowcattle.game.service.net.message.AbstractNetMessage;
import com.snowcattle.game.service.net.message.AbstractNetProtoBufMessage;
import com.snowcattle.game.service.net.message.factory.ITcpMessageFactory;
import com.snowcattle.game.service.net.session.NettySession;
import org.slf4j.Logger;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedDeque;
/**
* Created by jwp on 2017/2/9.
* 消息处理器
*/
public class NetProtoBufMessageProcess implements INetProtoBufMessageProcess, IUpdatable{
protected static final Logger logger = Loggers.sessionLogger;
protected static final Logger statLog = Loggers.serverStatusStatistics;
/** 处理的消息总数 */
protected long statisticsMessageCount = 0;
/**
* 网络消息处理队列
*/
private Queue<AbstractNetProtoBufMessage> netMessagesQueue;
private NettySession nettySession;
/** 中断消息处理 */
protected boolean suspendedProcess;
public NetProtoBufMessageProcess(NettySession nettySession) {
this.netMessagesQueue = new ConcurrentLinkedDeque<AbstractNetProtoBufMessage>();
this.nettySession = nettySession;
}
@Override
public void processNetMessage() {
int i = 0;
AbstractNetProtoBufMessage message = null;
while (!isSuspendedProcess() && (message = netMessagesQueue.poll())!= null && i < GlobalConstants.Constants.session_prcoss_message_max_size) {
i++;
long begin = 0;
if (logger.isInfoEnabled()) {
begin = System.nanoTime();
}
statisticsMessageCount++;
try {
NetMessageProcessLogic netMessageProcessLogic = LocalMananger.getInstance().getLocalSpringBeanManager().getNetMessageProcessLogic();
netMessageProcessLogic.processMessage(message, nettySession);
} catch (Exception e) {
if (logger.isErrorEnabled()) {
Loggers.errorLogger.error(ErrorsUtil.error("Error",
"#.QueueMessageExecutorProcessor.process", "param"), e);
}
if(e instanceof GameHandlerException){
GameHandlerException gameHandlerException = (GameHandlerException) e;
ITcpMessageFactory iTcpMessageFactory = LocalMananger.getInstance().get(ITcpMessageFactory.class);
AbstractNetMessage errorMessage = iTcpMessageFactory.createCommonErrorResponseMessage(gameHandlerException.getSerial(), gameHandlerException.COMMON_ERROR_STATE);
try {
nettySession.write(errorMessage);
}catch (Exception writeException){
Loggers.errorLogger.error(ErrorsUtil.error("Error",
"#.QueueMessageExecutorProcessor.writeErrorMessage", "param"), e);
}
}
} finally {
if (logger.isInfoEnabled()) {
// 特例,统计时间跨度
long time = (System.nanoTime() - begin) / (1000 * 1000);
if (time > 1) {
statLog.info("#CORE.MSG.PROCESS.STATICS Message id:"
+ message.getNetMessageHead().getCmd() + " Time:"
+ time + "ms" + " Total:"
+ statisticsMessageCount);
}
}
}
}
}
@Override
public void addNetMessage(AbstractNetMessage abstractNetMessage) {
this.netMessagesQueue.add((AbstractNetProtoBufMessage) abstractNetMessage);
}
@Override
public void close() {
this.netMessagesQueue.clear();
setSuspendedProcess(true);
}
@Override
public boolean update() {
try {
processNetMessage();
} catch (Exception e) {
Loggers.errorLogger.error(e.toString(), e);
}
return false;
}
public boolean isSuspendedProcess() {
return suspendedProcess;
}
public void setSuspendedProcess(boolean suspendedProcess) {
this.suspendedProcess = suspendedProcess;
}
}