在RxJava中同时从Socket读取和写入

时间:2016-04-03 17:24:41

标签: java sockets rx-java reactive-programming

我是一个试图完成以下简单任务的RxJava新手:

  • 通过套接字连接到定期发送数据的服务器
  • 在数据到达时读取数据
  • 如果套接字可写,则每隔n毫秒将心跳消息写入服务器

我写了一些工作RxJava程序到#34;连接和读取"和#34;连接和写",但现在我想编写一个同时执行这两个操作的程序。我有一个连接到套接字的功能:

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

...从中读取的功能

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

...以及测试可写性的函数(当它可写时它返回套接字)

Observable<SocketChannel> whenWritable(SocketChannel s) {

所以我的方法如下:

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"));
    });

当我运行程序时,&#34;读取n个字节&#34;消息定期出现,但心跳不会被写出来。

以下程序有效:

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

这里的问题是什么,是我在RxJava中做读写习惯的方法吗?

1 个答案:

答案 0 :(得分:1)

可能是因为readFromSocket(socket)是同步的,然后readFromSocket(socket).forEach会阻止,后面的代码将无法运行。您可以在readFromSocket(socket).forEach之后添加日志进行检查。

要解决此问题,您可以使用readFromSocket(socket).subscribeOn(Schedulers.io())在IO线程池中运行读取操作。