Rxjs 如何通过管道rx操作符组合片段数据?
我想用Rx来处理串口数据,数据包结构如下所示Rxjs 如何通过管道rx操作符组合片段数据?,rxjs,rx-java,reactive-programming,Rxjs,Rx Java,Reactive Programming,我想用Rx来处理串口数据,数据包结构如下所示 +-----------+--------+---------+ | Signature | Length | Payload | +-----------+--------+---------+ | 2 byte | 1 byte | ... | +-----------+--------+---------+ 但接收到的数据会有很多碎片。例如(签名为0xFC 0xFA) 数据1:0xFC 0xFA 0x02 0x01 0x01 0
+-----------+--------+---------+
| Signature | Length | Payload |
+-----------+--------+---------+
| 2 byte | 1 byte | ... |
+-----------+--------+---------+
但接收到的数据会有很多碎片。例如(签名为0xFC 0xFA)数据1:0xFC 0xFA 0x02 0x01 0x01 0xFC 0xFA 0x03 0x01//包含一个数据包和一个片段数据包
数据2:0x02 0x03 0xFC 0xFA 0x02 0x01 0x03//包含先前数据包和新数据包的连续片段 如何通过管道将运算符输出为
包1:0xFC 0xFA 0x02 0x01 0x01
包2:0xFC 0xFA 0x03 0x01 0x02 0x03
... 你需要一个有状态的观察者。它将让这些国家:
Packetizer
,该类将有两个感兴趣的方法:
public void nextByte(Char next);
public Observable<Packet> packetSource();
public void nextByte(Char next);
公共可观察包源();
在内部,它将保持状态,包括正文剩余部分的长度等。它还将具有一个
PublishSubject
,它将在构造每个数据包时发出该数据包。您正在按定义的模式拆分字节流。我不确定您是如何接收字节的,以及您将如何建模您的可观察的、可观察的
或可观察的
不管怎样,这里我猜的是用字符串翻译的,但是想法还是一样的。我选择了x
后跟y
作为模式(0xFC 0xFA
)
您可以在代码中找到我的注释:
final ImmutableList模式=ImmutableList.of(“x”,“y”);
可观测源=可观测
.fromArray(“x”、“y”、“1”、“2”、“3”、“x”、“y”、“4”、“5”、“x”、“y”、“y”、“1”、“x”、“y”、“x”、“x”、“x”、“4”、“6”、“x”)
.share()//发布到hot observable(我们将此源按其某些元素进行拆分)
//找到下一个模式
可观测下边界=源
.缓冲区(2,1)
.filter(对->CollectionUtils.isEqualCollection(模式,对));
//https://raw.githubusercontent.com/wiki/ReactiveX/RxJava/images/rx-operators/buffer2.png
//为找到的每个x启动一个缓冲区
//缓冲区(数据包)可能重叠
source.buffer(source.filter(e->e.equals(“x”)),
x->来源
.take(1)//x之后的下一个发射
.switchMap(y->y.equals(“y”)?
下一边界//如果为“y”,则查找下一个模式
:Observable.empty()//否则停止缓冲
)
)
.filter(packet->packet.size()>2)//不要使用错误的缓冲区,如[“x”,“4”](x后面不跟y),但不会丢失
.map(数据包->{
//每个数据包如下所示:
//[x,y,1,2,3,x,y]
//[x,y,4,5,x,y]
//[x,y,1,x,y]
//[x,y,x,4,6,x]
//由于边界封闭,事件来得太晚
//然后我们必须处理数据包(它与下一个数据包重叠)
列表结束=packet.subList(packet.size()-2,packet.size());
返回CollectionUtils.isEqualCollection(模式,结束)?packet.subList(0,packet.size()-2):packet;
})
.blockingSubscribe(e->System.out.println(e));
结果:
[x,y,1,2,3][x,y,4,5]
[x,y,1]
[x,y,x,4,6,x]
我试过你们两个的解决办法。都很好!