欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

netty+动态代理项目:客户端发送消息并同步获取结果

程序员文章站 2022-04-10 19:41:27
问题二:客户端发送完参数(接口名,参数,service名)后,服务端处理完数据在客户端的handler接收,而不是客户端发送消息并同步获取结果原有关代码为什么不直接发序列化后的json字符串呢,是因为直接发送,无法控制粘包分包的问题,在服务端加入长度解码器LengthFieldBasedFrameDecoder(),完美控制连续发送时的粘包问题。@Override public Object invoke(Object proxy, Method method, Object[] args)...

问题二:客户端发送完参数(接口名,参数,service名)后,服务端处理完数据在客户端的handler接收,而不是客户端发送消息并同步获取结果

原有关代码

为什么不直接发序列化后的json字符串,而是发送一个ByteBuf类型的数据,是因为直接发送,无法控制粘包分包的问题,在服务端加入长度解码器LengthFieldBasedFrameDecoder(),完美控制连续发送时的粘包问题。

@Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //jsonString是我在这处理好的一个String序列化后的json数据,代码太臭长,就不漏出来了。
        //影响观赏
        byte[] bytes = jsonString.getBytes("UTF-8");
        ByteBuf buf = Unpooled.buffer();
        buf.writeChar(100);
        buf.writeInt(bytes.length+4);
        buf.writeBytes(bytes);
        future.channel().writeAndFlush(buf);//客户端发送消息给客户端语句
        Object object = null;
        return object;
    }

下面是客户端接收处理后数据的类,只要处理完会自动进到这来(当然是在一直连接的前提下)
msg就是数据

public class ClientHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        String message = msg.toString();
        if (message != null) {
            Object data = JSONObject.parseObject(message, Object.class);
        }
    }
}

修改后代码

public class ClientHandler extends ChannelInboundHandlerAdapter {
    private static Logger logger = Logger.getLogger(ClientHandler.class);
    private static ChannelHandlerContext ctx;
    private static ChannelPromise promise;
    private static Object message;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        this.ctx = ctx;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        String message1 = msg.toString();
        if (message1 != null) {
            Object data = JSONObject.parseObject(message1, Object.class);
            message = data;
            promise.setSuccess();
        } else {ctx.fireChannelRead(msg);}
    }

    public synchronized ChannelPromise sendMessage(ByteBuf message) {
        while (ctx == null) {
            try {
                TimeUnit.MILLISECONDS.sleep(1);
            } catch (InterruptedException e) {
                logger.error("等待ChannelHandlerContext实例化过程中出错",e);
            }
        }
        promise = ctx.newPromise();
        ctx.writeAndFlush(message);
        return promise;
    }

    public Object getMessage(){return message;}
}

channelActive()方法是在启动客户端的时候进行ChannelHandlerContext实例化,自动调用。
而我对ChannelHandlerContext理解是一个通道。
代表了一个ChannelHandler和ChannelPipeline之间的关系,创建于ChannelHandler被载入到ChannelPipeline的时候,主要功能是管理ChannelPipeline中各个ChannelHandler的交互。

@Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //jsonString是我在这处理好的一个String序列化后的json数据,代码太臭长,就不漏出来了。
        //影响观赏
        byte[] bytes = jsonString.getBytes("UTF-8");
        ByteBuf buf = Unpooled.buffer();
        buf.writeChar(100);
        buf.writeInt(bytes.length+4);
        buf.writeBytes(bytes);
        ChannelPromise promise = clientHandler.sendMessage(buf);
        promise.await(6, TimeUnit.SECONDS);
        return clientHandler.getMessage();
    }

参考文章:https://blog.csdn.net/u011134399/article/details/109474008

有帮助的话,来个三连吧!!!

本文地址:https://blog.csdn.net/wyyzy0420/article/details/110188245

相关标签: netty java