use of com.nhnent.eat.common.PacketClassPool in project eat by nhnent.
the class NettyCommunication method receivePacket.
/**
* Receive packet from server
*
* @param clsPck Class type of receiving packet
* @return Received object which formatted given class type
*/
private Object receivePacket(final Class<?> clsPck) throws SuspendExecution, InterruptedException {
Object objReceivePacket;
Pair<String, byte[]> packet = null;
try {
packet = readRealResponse();
PacketClassPool classes = PacketClassPool.obj();
String receivedPacketName = packet.getKey();
String clsPckGetName = clsPck.getName();
// Value of clsPck.getName() is like 'com.nhnent.tardis.common.protocol.Base$AuthenticationRes',
// So remove prefix till '$'
String expectedPacketName;
if (clsPckGetName.contains("$")) {
expectedPacketName = clsPckGetName.split("\\$")[1];
} else {
String[] splitString = clsPckGetName.split("\\.");
expectedPacketName = splitString[splitString.length - 1];
}
if (!receivedPacketName.equals(expectedPacketName)) {
if (Config.obj().getCommon().isIgnoreUnnecessaryPacket()) {
logger.debug("[userId:{}]ignore received packet: {}", userInfo.get(), receivedPacketName);
objReceivePacket = receivePacket(clsPck);
} else {
throw new Exception("Received packet is different with expectation.\nExpect:" + expectedPacketName + "\nReceived:" + receivedPacketName);
}
} else {
objReceivePacket = StreamPacket.obj().decodePacket(userId, clsPck, packet.getValue());
}
} catch (TimeoutException e) {
logger.error("Timeout is raised. Receive Packet for [{}]", clsPck.getName());
return null;
} catch (Exception e) {
logger.error("Exception is raised. Receive Packet\nName:{}\nValue{}\n{}", clsPck.getName(), packet.getValue(), ExceptionUtils.getStackTrace(e));
return null;
}
return objReceivePacket;
}
use of com.nhnent.eat.common.PacketClassPool in project eat by nhnent.
the class Packet method generateHeader.
/**
* @param destination Destination of packet(Game, Chatting or and so on.)
* @param type Type of scenario unit
* @param msgName Name of packet
* @param subId SubID which for 1 player
* @param bodySize Size of body
* @return Generated packet header
* @throws Exception If reflection function is not found, it will raise exception
*/
private static byte[] generateHeader(final String destination, final String type, final String msgName, final String subId, final int bodySize) throws Exception {
final String baseHeader = ProtobufConfig.obj().getProtobuf().getHeaderPackageClassName() + "$Header";
final String baseHeaderBuilder = ProtobufConfig.obj().getProtobuf().getHeaderPackageClassName() + "$Header$Builder";
PacketClassPool classes = PacketClassPool.obj();
Object builder = classes.callFunction(baseHeader, null, "newBuilder", null);
classes.callFunction(baseHeaderBuilder, builder, "setSubid", subId);
if (type.equals(ScenarioUnitType.Request)) {
classes.callFunction(baseHeaderBuilder, builder, "setSeq", ++seqNo);
} else {
classes.callFunction(baseHeaderBuilder, builder, "setSeq", 0);
}
classes.callFunction(baseHeaderBuilder, builder, "setMsgName", msgName);
classes.callFunction(baseHeaderBuilder, builder, "setBodySize", bodySize);
classes.callFunction(baseHeaderBuilder, builder, "setService", destination);
Object header = classes.callFunction(baseHeaderBuilder, builder, "build", null);
return (byte[]) classes.callFunction(baseHeader, header, "toByteArray", null);
}
use of com.nhnent.eat.common.PacketClassPool in project eat by nhnent.
the class ProtoBufPacket method receivePacket.
/**
* Inspect packet and parse packet
* 1. Read packet header
* 2. If size of packet is lack to generated whole packet, it will wait next packet
* 3. If 2 more packets are exist in the given packet, it will insert it to given queue
* @param packets Queue of packets
* @param data Original packet byte
* @throws Exception Handle exception
*/
@Override
public final void receivePacket(Queue<Pair<String, byte[]>> packets, final byte[] data) throws Exception {
String receivedPacketName;
if (buffer.writableBytes() < data.length) {
int copyCount = buffer.writerIndex() - buffer.readerIndex();
buffer.resetWriterIndex();
buffer.writeBytes(buffer, buffer.readerIndex(), copyCount);
buffer.resetReaderIndex();
if (buffer.writableBytes() < data.length) {
int addCapacity = data.length - buffer.writableBytes();
buffer.capacity(buffer.capacity() + addCapacity);
}
}
buffer.writeBytes(data);
while (buffer.readableBytes() != 0) {
int headerSize = buffer.getByte(buffer.readerIndex());
int streamLen = buffer.readableBytes();
// If lack of header packet size
if (streamLen < headerSize + 1) {
// Add 1 byte for header size.
break;
}
final String baseHeader = ProtobufConfig.obj().getProtobuf().getHeaderPackageClassName() + "$Header";
final String baseHeaderBuilder = ProtobufConfig.obj().getProtobuf().getHeaderPackageClassName() + "$Header$Builder";
PacketClassPool classes = PacketClassPool.obj();
Object builder = classes.callFunction(baseHeader, null, "newBuilder", null);
try {
classes.callFunction(baseHeaderBuilder, builder, "mergeFrom", buffer.array(), buffer.readerIndex() + 1, headerSize);
} catch (Exception e) {
logger.error("Failed to decode packet.\nheaderSize:{}\nData:{}", headerSize, buffer.array());
throw e;
}
// Check and skip Ping packet
String msgName = (String) classes.callFunction(baseHeaderBuilder, builder, "getMsgName", null);
// logger.info("recv Msg Name : " + msgName);
if (msgName.equals("Ping")) {
logger.debug("received PING");
buffer.readerIndex(buffer.readerIndex() + 1 + headerSize);
continue;
}
boolean needToDecompress = false;
int bodySize;
int uncompressSize = (int) classes.callFunction(baseHeaderBuilder, builder, "getUncompressSize", null);
logger.debug("msgName=>{}, uncompressSize=>{}", msgName, uncompressSize);
bodySize = (int) classes.callFunction(baseHeaderBuilder, builder, "getBodySize", null);
int packetSize = 1 + headerSize + bodySize;
if (uncompressSize != 0) {
// Need to decompress packet
needToDecompress = true;
}
// If lack of packet size
if (packetSize > streamLen) {
break;
}
byte[] body;
if (needToDecompress) {
byte[] compressedBody = new byte[bodySize];
// begin : code for lz4 decompression
body = new byte[uncompressSize];
System.arraycopy(buffer.array(), buffer.readerIndex() + 1 + headerSize, compressedBody, 0, bodySize);
LZ4Factory factory = LZ4Factory.fastestInstance();
LZ4FastDecompressor decompressor = factory.fastDecompressor();
decompressor.decompress(compressedBody, body);
// end : code for lz4 decompression
// begin : code for snappy decompression
// body = Snappy.uncompress(compressedBody);
// end : code for snappy decompression
} else {
body = new byte[bodySize];
System.arraycopy(buffer.array(), buffer.readerIndex() + 1 + headerSize, body, 0, bodySize);
}
if (headerSize != 0) {
receivedPacketName = (String) classes.callFunction(baseHeaderBuilder, builder, "getMsgName", null);
packets.add(new Pair<>(receivedPacketName, body));
}
buffer.readerIndex(buffer.readerIndex() + packetSize);
}
}
Aggregations