Java Netty - отправлять результат клиенту как StringEncoder или ObjectEncoder в зависимости от входного сообщения? - PullRequest
0 голосов
/ 23 октября 2018

Я новичок в Netty, и до сих пор существует работающий клиент-сервер, который может обрабатывать String-сообщение с помощью StringEncoder и StringDecoder, например:

        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap.group(bossGroup, workerGroup)
                       .channel(NioServerSocketChannel.class)
                       .handler(new LoggingHandler(LogLevel.TRACE))
                       .childHandler(new ChannelInitializer<SocketChannel>() {
                                            @Override
                                            public void initChannel(SocketChannel ch) throws Exception {
                                                ch.pipeline().addLast(
                                                    new LoggingHandler(LogLevel.TRACE),
                                                    new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Delimiters.lineDelimiter()),
                                                    new StringEncoder(),
                                                    new StringDecoder(),
                                                    new ReceiveMessageCommunicatorHandler(localNode, inpeerNodeRegistry, outpeerNodeRegistry));

Входное сообщение выглядит так: excute_this и сервер отправляет обратно: ok .

Теперь мне нужно, чтобы сервер получил новое текстовое сообщение: get_object , он долженотправьте обратно любому клиенту (например, telnet или Java-приложение, которое использует простой сокет) сериализованный объект в виде байтового массива.Затем в этом клиенте он может десериализовать этот объект как объект Java.

Я знал, что ObjectEncoder () , кажется, способ сделать это.Но он также сериализует ответ, который должен быть String, для сериализованного объекта, в то время как он должен делать это для некоторых конкретных сообщений (например: get_object * только 1017 *).

Как я могу сказать Netty, когда ондолжен кодировать результат как StringEncoder и когда следует кодировать как Serialized Object как байтовый массив?

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Спасибо за предложение Рияфа Абдул Хамид

Он может динамически переключать кодировщик, как в этом коде, когда сервер получает сообщение и пишет ответ клиенту.

@Override
protected void channelRead0(ChannelHandlerContext ctx, String message) throws Exception {
    InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
    MessageContainer messageContainer = new MessageContainer(message, address);
    log.debug("\n");
    log.debug("Message received: {}", message);

    // Handle received message and write result back to the sender
    Object response = this.handleMessage(messageContainer);
    if (response instanceof String) {
        ctx.channel().pipeline().names();
        ctx.channel().pipeline().remove(ObjectEncoder.class);
        ctx.channel().pipeline().addFirst(new StringEncoder());
    }

    if (response != null) {
        ctx.write(response);
        ctx.flush();
    }
    ctx.close();
}
0 голосов
/ 23 октября 2018

Возможно динамическое изменение конвейера.Когда вы получаете сообщение get_object , вы можете просто удалить StringEncoder и добавить ObjectEncoder в соответствующий ChannelInboundHandler

   ChannelPipeline p = ctx.pipeline();
    if (p.get(StringEncoder.class) != null) {
        p.remove(StringEncoder.class);
    }
    p.addLast(new YourObjectEncoder())

. Если вы знаете имя вашего кодировщика, выможно сделать замену:

p.replace("encoder", "encoder", new YourObjectEncoder());
...