如何在NodeJS中编写双向双工流

时间:2013-10-16 11:06:39

标签: node.js sockets stream duplex

在NodeJS的最新几个版本(编写时为v0.10.X)中,Streams API经过了重新设计的欢迎,我现在就开始使用它。

我想用一个实现协议的对象包装套接字的输入输出。

所谓的Duplex接口,似乎只是任何可读写的流(如套接字)。

目前尚不清楚双工是否应该像A或B,或者它是否无关紧要。

   +---+        +---+
-->| A |-->     |   |-->
   +---+        | B |
                |   |<--
                +---+

具有两个可写和两个可读对象的对象的正确代码结构/接口是什么?

+--------+   +----------+   +----
|       r|-->|w        r|-->|w    
| socket |   | protocol |   | rest of app
|       w|<--|r        w|<--|r    
+--------+   +----------+   +----

上图中的问题是protocol对象需要两个单独的read方法和两个write方法。

在我的脑海中,我可以使协议生成“左”和“右”双工对象,或“进入”和“出”双工对象(以不同方式对其进行切片)。

这些都是首选方式,还是有更好的解决方案?

2 个答案:

答案 0 :(得分:7)

          |      app      |
          +---------------+
              ^       |
              |       V      
           +-----+ +-----+
           |     | |     |
+----------|     |-|     |-+
| protocol | .up | |.down| |
+----------|     |-|     |-+
           |     | |     |
           +-----+ +-----+
              ^       |
              |       V
          +---------------+
          |     socket    |

我的解决方案是创建一个Protocol类,它创建了一个Up Transform和一个Down Transform

协议构造函数在构造Up和Down转换时传递引用(自身)。然后,每个上下变换中的_transform方法可以根据需要在另一个push或两者上调用Transform。公共状态可以保存在Protocol对象中。

答案 1 :(得分:1)

双工流与图B类似,至少对用户而言如此。更完整的流视图将包括生产者(源)与消费者(用户)。查看我之前的answer。尽量不要从消费者的角度考虑读/写。

您正在做的是在套接字上为协议构建一个薄层,因此您的设计是正确的:

                         -------+     +----------+     +------
                               r|---->|         r|---->|      
                         socket |     | protocol |     | rest of app
                               w|<----|         w|<----|      
                         -------+     +----------+     +------

您可以对协议部分使用双工或转换。

                 +---------+--------+---------+       +------------------+ 
                 | _write->|        |         |r      |   Transform  ->  |r
                 |-----------Duplex-----------|       +------------------+    
                 |         |        | <-_read |w      |   <- Transform   |w
                 +---------+--------+---------+       +------------------+

使用内部_read,_write处理传入/传出数据的协议相关处理。或者你可以改变流。您可以将协议管道连接到套接字和套接字协议。