首页 新闻 会员 周边 捐助

vertx tcp能同步发送接收吗

0
悬赏园豆:10 [已解决问题] 解决于 2023-07-23 08:16

我想发送一条完毕,接受完再去发送另一条,现在是异步的,一下两条全发过去了,导致接收不对。

        long timerId = vertx.setPeriodic(10000, res -> {

            CLIENT_MAP.forEach((key, socket) -> msgList.forEach(msg -> {
                vertx.setTimer(5000, time -> {
                   receiveMsg1(socket, msg);
                    log.info("测试定时=====》 {}", LocalDateTime.now());
                });

            }));
        });


    private void receiveMsg1(NetSocket socket, String msg) {
        log.info("定时任务发送的消息到的消息 {}  {}", msg, LocalDateTime.now());
        socket.write(Buffer.buffer((msg)), ar1 -> {
            if (ar1.succeeded()) {
//                ThreadUtil.sleep(3000);
                // 发送指令失败 进行记录
                socket.handler(receive ->  {
                    log.info("接收到的消息 {} {}", msg,  receive);
                });
            }
        });
    }


溢性循环的主页 溢性循环 | 初学一级 | 园豆:131
提问于:2023-07-22 12:04
< >
分享
最佳答案
1

如果你想要实现同步发送和接收,可以使用Vert.x提供的异步编程模型来实现。

一种方式是使用Vert.x的Future/Promise机制。你可以使用Promise来表示发送操作的完成,并在Promise的完成处理程序中发送下一条消息。示例代码如下:

private void receiveMsg1(NetSocket socket, String msg) {
    log.info("定时任务发送的消息到的消息 {}  {}", msg, LocalDateTime.now());

    Promise<Void> sendPromise = Promise.promise();
    socket.write(Buffer.buffer(msg)).onComplete(ar1 -> {
        if (ar1.succeeded()) {
            socket.handler(receive ->  {
                log.info("接收到的消息 {} {}", msg,  receive);
                sendNextMessage(socket);
            });
            sendPromise.complete();
        } else {
            sendPromise.fail(ar1.cause());
        }
    });

    // 等待发送操作完成
    sendPromise.future().await();
}

private void sendNextMessage(NetSocket socket) {
    // 发送下一条消息
    // ...
}

上述代码中,使用Promise来表示发送操作的完成情况,并在发送完成后调用sendNextMessage方法发送下一条消息。使用future().await()可以使代码在发送操作完成前阻塞。

另外一种方式是使用异步编程的回调嵌套。在发送完成的回调函数中发送下一条消息。示例代码如下:

private void receiveMsg1(NetSocket socket, String msg) {
    log.info("定时任务发送的消息到的消息 {}  {}", msg, LocalDateTime.now());

    socket.write(Buffer.buffer(msg)).onComplete(ar1 -> {
        if (ar1.succeeded()) {
            socket.handler(receive ->  {
                log.info("接收到的消息 {} {}", msg,  receive);
                sendNextMessage(socket);
            });
        } else {
            // 处理发送失败的情况
        }
    });
}

private void sendNextMessage(NetSocket socket) {
    // 发送下一条消息
    // ...
}

使用上述方式,代码将按照你期望的顺序发送和接收消息。需要注意的是,这样的同步发送和接收可能会导致阻塞并等待消息发送和接收完成,可能会影响系统的响应性能。请根据实际需求谨慎使用。

收获园豆:10
lanedm | 老鸟四级 |园豆:2396 | 2023-07-22 14:03

有个问题 我是先定义一个集合 msgList 去循环发送信息,但是每次都是消息全发过去了,后面一个个接受,怎么才能做到循环一个发一次 接受完,再发另一个呢

溢性循环 | 园豆:131 (初学一级) | 2023-07-22 17:13

@溢性循环: 以下是一个示例代码,在发送消息前,将所有要发送的消息存储在一个集合中。例如,定义一个List<String>类型的消息列表。
创建一个变量来跟踪当前发送的消息索引,初始化为0,通过递归进行消息发送:

import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetSocket;

import java.util.ArrayList;
import java.util.List;

public class Main {

    private static void receiveMsg1(NetSocket socket, List<String> msgList) {
        int initialIndex = 0;
        sendNextMessage(socket, msgList, initialIndex);
    }

    private static void sendNextMessage(NetSocket socket, List<String> msgList, int currentIndex) {
        if (currentIndex < msgList.size()) {
            String nextMsg = msgList.get(currentIndex);
            socket.write(Buffer.buffer(nextMsg)).onComplete(ar1 -> {
                if (ar1.succeeded()) {
                    socket.handler(receive ->  {
                        System.out.println("接收到的消息: " + nextMsg + " - " + receive.toString());

                        // 发送下一条消息
                        sendNextMessage(socket, msgList, currentIndex + 1);
                    });
                } else {
                    // 处理发送失败的情况
                }
            });
        }
    }

    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        NetSocket socket = createYourNetSocket(vertx); // 创建你的NetSocket

        List<String> msgList = new ArrayList<>();
        msgList.add("消息1");
        msgList.add("消息2");
        msgList.add("消息3");

        receiveMsg1(socket, msgList);
    }

    // 创建你的NetSocket,此处仅作为示例
    private static NetSocket createYourNetSocket(Vertx vertx) {
        // 创建和配置NetSocket对象
        // ...

        return netSocket;
    }
}

在示例代码中,你需要根据实际情况创建和配置NetSocket对象,并将其传递给receiveMsg1方法。同时,在msgList中添加你想要发送的消息。当运行示例代码时,它将按顺序发送每条消息,并在接收到响应后发送下一条消息。请根据你的实际需求进行适当的修改和调整。

lanedm | 园豆:2396 (老鸟四级) | 2023-07-23 00:02

@lanedm: 感谢老哥,老哥你太牛了 解决了,我原本是直接使用 msgList.forEach 循环调用发送消息的方法,发现打印日志的时候,发送的消息总是最后一条 十分感谢,而且昨晚上测试也是一直发送不成功。试试你的没问题。感谢感谢

溢性循环 | 园豆:131 (初学一级) | 2023-07-23 08:15

@lanedm: 现在还有个问题 我用java vertx写客户端,服务端测试没问题,但是如果java启动服务端,硬件作为客户端,还是有消息无法接收完再发下一个消息的问题。这个怎么办?

溢性循环 | 园豆:131 (初学一级) | 2023-08-09 13:18

解决了 使用解析器防止拆包 粘包

代码优化为

import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetSocket;

import java.util.ArrayList;
import java.util.List;

public class Main {

    private static void receiveMsg1(NetSocket socket, List<String> msgList) {
        int initialIndex = 0;
        sendNextMessage(socket, msgList, initialIndex);
    }

    private static void sendNextMessage(NetSocket socket, List<String> msgList, int currentIndex) {
        if (currentIndex < msgList.size()) {
            String nextMsg = msgList.get(currentIndex);
            socket.write(Buffer.buffer(nextMsg)).onComplete(ar1 -> {
                if (ar1.succeeded()) {
				    // 解决拆包粘包问题
					final RecordParser parser = RecordParser.newDelimited('尾部指令', receive -> {
                        String heartStr =  HexUtil.encodeHexStr(receive.getBytes(), false).toUpperCase();
                        System.out.println("接收到的消息: " + sendMsg.get() +" " + LocalDateTime.now() + " - " + heartStr);
                        // todo 具体逻辑处理
                        // 发送下一条消息
                        sendNextMessage(socket, msgList, currentIndex + 1);
                    });			
                    socket.handler(parser);
                } else {
                    // 处理发送失败的情况
                }
            });
        }
    }

    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        NetSocket socket = createYourNetSocket(vertx); // 创建你的NetSocket

        List<String> msgList = new ArrayList<>();
        msgList.add("消息1");
        msgList.add("消息2");
        msgList.add("消息3");

        receiveMsg1(socket, msgList);
    }

    // 创建你的NetSocket,此处仅作为示例
    private static NetSocket createYourNetSocket(Vertx vertx) {
        // 创建和配置NetSocket对象
        // ...

        return netSocket;
    }
}
溢性循环 | 园豆:131 (初学一级) | 2023-08-25 10:25
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册