me.ferrybig.p2pnetwork.codec.PacketPreProcessor.java Source code

Java tutorial

Introduction

Here is the source code for me.ferrybig.p2pnetwork.codec.PacketPreProcessor.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package me.ferrybig.p2pnetwork.codec;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import java.util.function.Function;
import java.util.logging.Logger;
import me.ferrybig.p2pnetwork.Address;
import me.ferrybig.p2pnetwork.codec.packets.Packet;
import me.ferrybig.p2pnetwork.codec.packets.ProcessedPacket;
import me.ferrybig.p2pnetwork.codec.packets.RelayPacket;

/**
 *
 * @author Fernando
 */
public class PacketPreProcessor extends SimpleChannelInboundHandler<Packet> {

    private final Address connection;

    public PacketPreProcessor(Address connection) {
        super(false);
        this.connection = connection;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Packet msg) throws Exception {
        try {
            Address from;
            Function<Packet, ChannelFuture> reply;
            if (msg instanceof RelayPacket) {
                RelayPacket relayPacket = (RelayPacket) msg;
                int packetId = relayPacket.getData().readInt();
                from = relayPacket.getFrom();
                msg = PacketMap.readPacket(packetId, relayPacket.getData());
                relayPacket.release(); // This is a safe release
                reply = p -> {
                    ByteBuf wrapped = ctx.alloc().buffer();
                    try {
                        wrapped.writeInt(PacketMap.getPacketId(p));
                        p.write(wrapped);
                        return ctx.writeAndFlush(
                                new RelayPacket(wrapped.retain(), relayPacket.getAddress(), from, 255));
                    } finally {
                        p.release();
                        wrapped.release();
                    }
                };
            } else {
                from = connection;
                reply = ctx::writeAndFlush;
            }
            ctx.fireChannelRead(new ProcessedPacket(from, ctx.channel(), (Packet) msg.retain(), reply));
        } finally {
            msg.release();
        }
    }

    private static final Logger LOG = Logger.getLogger(PacketPreProcessor.class.getName());

}