Search in sources :

Example 1 with PacketClassPool

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;
}
Also used : PacketClassPool(com.nhnent.eat.common.PacketClassPool) TimeoutException(org.jboss.netty.handler.timeout.TimeoutException) TimeoutException(org.jboss.netty.handler.timeout.TimeoutException)

Example 2 with PacketClassPool

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);
}
Also used : PacketClassPool(com.nhnent.eat.common.PacketClassPool)

Example 3 with PacketClassPool

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);
    }
}
Also used : LZ4FastDecompressor(net.jpountz.lz4.LZ4FastDecompressor) PacketClassPool(com.nhnent.eat.common.PacketClassPool) LZ4Factory(net.jpountz.lz4.LZ4Factory) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException)

Aggregations

PacketClassPool (com.nhnent.eat.common.PacketClassPool)3 InvalidProtocolBufferException (com.google.protobuf.InvalidProtocolBufferException)1 LZ4Factory (net.jpountz.lz4.LZ4Factory)1 LZ4FastDecompressor (net.jpountz.lz4.LZ4FastDecompressor)1 TimeoutException (org.jboss.netty.handler.timeout.TimeoutException)1