简体   繁体   English

在RxJava中同时从Socket读写

[英]Read and write from a Socket simultaneously in RxJava

I'm an RxJava newbie trying to accomplish the following simple task: 我是一个试图完成以下简单任务的RxJava新手:

  • connect via a socket to a server that regularly sends data 通过套接字连接到定期发送数据的服务器
  • read the data as it arrives 在数据到达时读取数据
  • write a heartbeat message to the server every n milliseconds if the socket is writeable 如果套接字是可写的,则每隔n毫秒向服务器写一条心跳消息

I wrote working RxJava programs to "connect and read" and "connect and write", but now I want to write a program that does both. 我编写了工作RxJava程序来“连接和读取”和“连接和写入”,但现在我想写一个同时执行这两个程序的程序。 I have a function to connect to a socket: 我有一个连接到套接字的功能:

Observable<SocketChannel> connect(String host,int port) { ...

...a function to read from it ...从中读取的功能

Observable<byte[]> readFromSocket(SocketChannel s) {

...and a function to test for writeability (it returns the socket when it's writeable) ...以及测试可写性的函数(它在可写时返回套接字)

Observable<SocketChannel> whenWritable(SocketChannel s) {

So my approach looks like the following: 所以我的方法如下:

connect("localhost", 31337).forEach(socket -> {
    readFromSocket(socket)
        .forEach(bytes -> printf("read %d bytes",bytes.length);
    Observable
        .interval(2500, TimeUnit.MILLISECONDS)
        .flatMap(ignore -> whenWritable(socket))
        .forEach(ignore -> println("write heart beat"));
    });

When I run the program, the "read n bytes" messages appear regularly, but the heart beats are not written. 当我运行程序时,“读取n个字节”消息会定期出现,但不会写入心跳。

The following program works, however: 但是,以下程序有效:

connect("localhost", 31337)
    .flatMap(s -> 
        Observable
            .interval(2500, TimeUnit.MILLISECONDS)
            .flatMap(ignore -> whenWritable(s)))
    .forEach(ignore -> println("write heart beat"));

What's the problem here, and is my method of doing read and write customary in RxJava? 这里有什么问题,是我在RxJava中做读写习惯的方法吗?

It's probably because readFromSocket(socket) is synchronous, then readFromSocket(socket).forEach will block and the codes after it won't be able to run. 这可能是因为readFromSocket(socket)是同步的,然后readFromSocket(socket).forEach将阻塞,并且后面的代码将无法运行。 You can add a log after readFromSocket(socket).forEach to check it. 您可以在readFromSocket(socket).forEach之后添加日志来检查它。

To resolve this issue, you can use readFromSocket(socket).subscribeOn(Schedulers.io()) to run the read actions in the IO thread pools. 要解决此问题,可以使用readFromSocket(socket).subscribeOn(Schedulers.io())在IO线程池中运行读取操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM