Добрый вечер. Постараюсь расписать проблему развернуто т.к задав вопрос на
stackoverflow я так и не получил ответ.
Итак. Имеем сервер на java с использованием фреймворка
Netty.io.
На сервер приходят пакеты от клиента на C# в виде:
[2byte длина][1byte тип][Xbyte protobuf данные]
Сервер в своей pipeline выкачивает нужный frame исходя из байтов длинны. И в итоге в обработчик приходит 1 frame: [1byte тип][Xbyte protobuf data] это и есть 1 пакет от клиента который нужно передать на обработку логике не задерживая при этом потоки Netty
Для пущей наглядности приведу код описанного выше
Здесь просто инициализация netty
private static void start(){
LOG.info("Starting netty");
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup(3);
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.localAddress(new InetSocketAddress(Config.PORT))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast("Register",new RegisterHandler());
ch.pipeline().addLast("FrameDecoder",new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN,27,0,2,0,2,true));
ch.pipeline().addLast(new ByteToPackageDecoder());
}
});
ChannelFuture f = b.bind().sync();
f.channel().closeFuture().sync();
} catch (Exception ex) {
}
finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
далее код ByteToPackageDecoder хэндлера. Он расширяет extends MessageToMessageDecoder
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
Logic.listMSG.add(in);
Logic.getLogin();
int bits32 = (int) in.getByte(0) & 0xff; //Читаем правильно 1 байт(убираем отрицательные числа)
LOG.info("Bytes to frame:" + in.readableBytes() + "READ 1 byte: " + bits32);
byte[] buf = new byte[in.readableBytes() - 1];
in.getBytes(1, buf);
Package p = new Package(1, buf, ctx);
switch (bits32) {
case 1:
Login1PackageOuterClass.Login1Package Login1Package = Login1PackageOuterClass.Login1Package.parseFrom(buf);
LOG.debug("Read message : " + Login1Package.getLogin());
}
}
Это лишь мои тесты, и грубый набросок. Как видите я привожу 1 байт типа в читаемый вид что бы видов пакетов у меня было 255. Далее извлекаю protobuf данные и пробую достать логин. Все работает.
НО! есть одно НО. Это все в pipeline и этого допускать нельзя.
Я понимаю мне нужно сделать отдельный поток серверной логики и стартовать его вместе с netty для теста я создаю public class Logic implements Runnable
Который имеет статический public static BlockingQueue listMSG = new PriorityBlockingQueue(1000);
Для добавление пакетов в очередь ну и бесконечный While для чтения этого списка.
И вот собственно в чем вопрос. Есть несколько вариантов развития событий..
1. Я могу передавать ByteBuf такого вида [1byte тип][Xbyte protobuf data] для обработки логики. А в логике уже производить присвоение protobuf данных нужному экземпляру
Login1PackageOuterClass.Login1Package Login1Package = Login1PackageOuterClass.Login1Package.parseFrom(buf);
в конструкции Switch(1byte тип)
2. Я также могу воспользоваться рефлексией создавать новый объект Package передавая тип пакета. А потом записывать уже в него все данные из protobuf. Передавать в очередь уже этот Package.
В логике же я буду просто доставать методы уже рефлексией. (на самом деле методов то не много, у каждого пакета будер read и send)
Больше вариантов мои знания увидеть не позволяют...
1 вариант мне не нравится тем что мне необходимо передавать канал(сокет) в игровую логику, что бы потом я мог ответить (после прохождения бд и т.д). А так я буду лишь передавать те же данные логике.
2 вариант мне кажется слишком медленным т.к я считаю излишним применение рефлексии когда я знаю все возможные варианты сообщений.
Подскажите правильный подход к архитектуре подобного рода? Мне нужно всего лишь поместить мои пакеты в очередь на обработку игровой логике. Например в BlockingQueue и все.. А в логике достать...
И я не понимаю как их правильнее привести к одному типу....