package com.snowcattle.game.service.net;
import com.snowcattle.game.common.constant.Loggers;
import com.snowcattle.game.manager.LocalMananger;
import com.snowcattle.game.service.rpc.server.RemoteRpcHandlerService;
import com.snowcattle.game.service.rpc.server.RpcMethodRegistry;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import java.lang.reflect.Method;
/**
* Created by jwp on 2017/3/7.
* rpc协议处理handler
*/
public class GameNetRPCServerHandler extends SimpleChannelInboundHandler<RpcRequest> {
private Logger logger = Loggers.rpcLogger;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
}
@Override
public void channelRead0(final ChannelHandlerContext ctx,final RpcRequest request) throws Exception {
RemoteRpcHandlerService remoteRpcHandlerService = LocalMananger.getInstance().getLocalSpringServiceManager().getRemoteRpcHandlerService();
remoteRpcHandlerService.submit(new Runnable() {
@Override
public void run() {
if(logger.isDebugEnabled()) {
logger.debug("Receive request " + request.getRequestId());
}
RpcResponse response = new RpcResponse();
response.setRequestId(request.getRequestId());
try {
Object result = handle(request);
response.setResult(result);
} catch (Throwable t) {
response.setError(t.toString());
logger.error("RPC Server handle request error",t);
}
ctx.writeAndFlush(response).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture) throws Exception {
if(logger.isDebugEnabled()) {
logger.debug("Send response for request " + request.getRequestId());
}
}
});
}
});
}
private Object handle(RpcRequest request) throws Throwable {
String className = request.getClassName();
RpcMethodRegistry rpcMethodRegistry = LocalMananger.getInstance().getLocalSpringServiceManager().getRpcMethodRegistry();
Object serviceBean = rpcMethodRegistry.getServiceBean(className);
Class<?> serviceClass = serviceBean.getClass();
String methodName = request.getMethodName();
Class<?>[] parameterTypes = request.getParameterTypes();
Object[] parameters = request.getParameters();
if(logger.isDebugEnabled()) {
logger.debug(serviceClass.getName());
logger.debug(methodName);
for (int i = 0; i < parameterTypes.length; ++i) {
logger.debug(parameterTypes[i].getName());
}
for (int i = 0; i < parameters.length; ++i) {
logger.debug(parameters[i].toString());
}
}
// // Cglib reflect 反射
// FastClass serviceFastClass = FastClass.create(serviceClass);
// FastMethod serviceFastMethod = serviceFastClass.getMethod(methodName, parameterTypes);
// return serviceFastMethod.invoke(serviceBean, parameters);
//jdk1.7 原生反射速度大于cglib 取消cglib
Method method = serviceClass.getMethod(methodName, parameterTypes);
return method.invoke(serviceBean, parameters);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
if(logger.isErrorEnabled()) {
logger.error("server caught exception", cause);
}
ctx.close();
}
}