当前位置: 首页 > 知识库问答 >
问题:

Java Netty-根据输入消息将结果作为StringEncoder或ObjectEncoder发送给客户端?

曹智
2023-03-14

我是Netty的新手,到目前为止,有一个可以使用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_对象,它应该将一个序列化对象作为字节数组发送回任何客户端(例如:telnet或使用普通套接字的java应用程序)。然后在这个客户机中,它可以将这个对象反序列化为Java对象。

我知道ObjectEncoder()似乎是解决这个问题的方法。但是,它还将应该是字符串的响应序列化到序列化对象,同时它应该为某些特定消息(例如:仅get_对象)执行此操作。

我如何告诉Netty何时应该将结果编码为StringEncoder,何时应该将序列化对象编码为字节数组?

共有2个答案

彭硕
2023-03-14

感谢里亚法·阿卜杜勒·哈米德的建议

当服务器接收到消息并将响应写入客户端时,它可以动态地切换编码器,如下面的代码所示。

@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();
}
温翔宇
2023-03-14

可以动态修改管道。当您收到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());
 类似资料:
  • 问题内容: 向所有客户端发送消息效果很好,但是我想向特定的用户名发送消息。我的server.js文件看起来像。它的作用是在运行时,客户端代码将用户添加到对象用户名以及套接字对象中。并立即将单个消息返回给每个连接的客户端。 发出消息的部分 问题答案: 试试这个: socket.id由socket.io保存,并且包含客户端的唯一ID。您可以使用以下命令进行检查:

  • 问题内容: 我只能在用户的套接字ID直接存储在io.sockets.on(’connect’)函数中时向用户发出消息。我不知道为什么在登录后尝试存储其套接字ID时为什么不起作用。 加工: 无法运作: JavaScript客户端代码段 解决方案:感谢@alessioalex, 我不得不从登录页面中删除对socket.io的引用,并将以下内容添加到io.sockets.on(’connection’)

  • 在socket.io中,如果要将消息发送到特定的房间,通常在服务器端使用特定的语法:。 但是客户机(我指的是在浏览器中运行的socket.io相关代码)如何指示消息应该发送到特定的房间? 还是socket.io客户端库也为此目的提供了特定的语法? 编辑:澄清一下,我上面的建议似乎起作用了,我只是不确定是否有更好的解决方案。

  • 如何在聊天客户端发送媒体消息?我使用的是JS SDK,基于教程https://www.twilio.com/docs/api/chat/guides/media-support,但是出现了错误。我使用的方法如下所示: 错误消息:

  • 问题内容: 这段代码一切正常(将其缩短以便更好地阅读)。 当向服务器发送请求时,服务器会立即响应他。但是,其他客户端看不到响应消息。 因此,我想进一步说明:当客户端向服务器发送请求时,服务器将响应所有客户端,以便所有客户端都能看到消息。 我怎样才能做到这一点?有任何示例或不错的入门教程吗? 提前致谢! 服务器: 问题答案: 您必须使用连接池将消息广播到所有连接。您可以将其用作教程/示例http:/

  • 我想使用贝宝来允许我的客户用信用卡或借记卡付款,我已经允许用贝宝付款,我知道在登录贝宝表单的按钮下,它的一个按钮上写着“用信用卡或借记卡付款”,但我想让用户直接从脚本到贝宝客人结账。 我使用PayPal SDK,这是我的代码: 我需要这个地方 而不是这个