我使用websocket-sharp 连接了socket服务器,并将来回应答的逻辑代码都写在了OnMessage里面,如图:
在我标记的地方,正常情况下服务器会返回消息A,我判断是消息A,就去做处理。但是现在有一种特殊情况,服务器除了回复我消息A,还会紧跟着发过来一条消息B,这种情况我需要做另一种处理。但是我目前的逻辑好像处理不了这种情况。socket消息如下图:
第一种情况
第二种情况
现在就是当消息A进到这里的时候,我不能直接就去处理,需要判断是否后面还有消息B,我不知道如何实现这个逻辑。因为两条消息不是一起过来的,如果合并为一条消息过来就很好办。但是现在消息A和B会依次进到这里,A过来的时候程序不能往下走,要等待 判断会不会有B第二次进到这里。我的想法是当消息A进来的时候,让程序等待,比如50ms,如果有消息B进来就是第二种情况,否则就是第一种情况。或者将消息A以及后面50ms的消息都先记录下来,后面一起判断,含有B就是第二种情况,不含就是第一种。但是我都不知道该如何实现。
onmessage中增加对A和A+B的处理逻辑,如果是A,则看前一个A消息记录是否处理,如果未处理立刻处理并清空前一个A记录,本次A则先不处理但是存储下来(作为下一次消息的前一个A消息记录),并启动一个定时器(如100ms),在定时器中进行消息A的处理并清除A消息;如果是B,则将之前消息A取出与B形成A+B进行处理,并将A消息存储清空。这样就可以实现对消息的A+B的即时处理和独立消息A的延后处理。
收到消息A时,保留A的数据,启动一个处理线程。
用多线程,A过来的时候你就先阻塞着。等得到B再处理行不行。
收到A的时候先让它等待一会,等到收到B再处理, (1)客户端同步监听来自服务器端的数据(开启子线程监听)
(2)客户端向服务器端发送数据(主线程发送,并控制)
(3)IsOnline判断连接是否中断,如中断则子线程结束执行
收到A消息能检测到吧,把A信号挂起,从检测到A信号开始计时,计时时间可以自行设定吧,也可以定死50ms,计时运行时间能检测吧,比如运行到30ms时B信号检测到了,这时B信号也挂起,计时复位,重新开始计时,检测50ms内是否有信号发来,有接着挂起,没有就将所有挂起信号合并处理。
把a存起来,在处理b,c井这个东西不好
如果是我,我会使用两个线程,一个是数据接收线程,一个是数据处理线程
定义一个数据队列(链表、队列等都可以),两个线程共享,要加锁,数据结构体包括时间戳,这个是你判断A和B的关键
数据接收线程收到数据后放到数据队列,因为有时间戳,数据处理线程里的处理逻辑你可以自己判断
这个方法耦合度低
是你理解错了。onMessage是每次有消息来的时候都会被调用1次,你只需要在onMessage里面判断是消息A做A的逻辑处理,判断是消息B就做B的逻辑处理。并不需要判断消息A后面有没有消息B,因为每一条消息都会进入这个onMessage方法。
如有帮助,请采纳,十分感谢!
自己写个消息存储队列,收到消息就将内容写入队列里放着,然后另外启动另外一个线程定时从队列里面拿消息判断处理应答逻辑
如果是这样的话,不急于回复,收到A消息=========一直等待,收到下一条消息,如果是需要一起处理的消息,比如B,那么就AB一起处理,如果又收到一条A,那就处理前一条A,下一条A继续等待,这样逻辑上也没有问题。
我看回答里大部分都是建议把消息A放缓存、map、列表等等吧,或者干脆就是阻塞,开新线程等消息B。
我觉得这样处理不好,不够严谨。
我的想法是改造消息,消息体加一个域,标记为消息的id,单独的消息A此域为空。消息A+B这种,这个域标记为同样的id,若onmessage解析消息发现这个域有id值,则表示有消息B正在赶来,其id也是这个值。等待之即可。
进来学习一下
我不想多赘述了
几个关键词题主自己搜,我讲的能理解理解,不能理解我也没办法。
关键词
1.Rx.net Zip方法
2.Tpl Dataflow JoinBlock方法
3.传统状态机,上一条A压栈不处理,等B来了,把A出栈
另外实际处理中请注意timeout,因为我们逻辑上不能排除对方绝对不错,所以如果A压栈了,B就是不来就是超时了,需要逻辑上保证这类情况的处理
看目前的逻辑应该加一个缓存机制就可以了
分两种情况
一、A和B消息是否有相同的一个唯一标识,就是能确定B1是紧跟着A1过来的数据。
二、A和B没有唯一标识。
第一种情况
1、A消息来了 记录A消息标识到Hashtable key值 ,A消息内容和A消息时间记录到Hashtable value值
2、B消息来了查询Hashtable是否有A消息
3、如果B消息没有来不用处理 等待下一条消息到来。假如A消息1s过期 则清除Hashtable中超过1s的数据
第二种情况
1、直接缓存A消息 和时间 假如A消息1s过期 如果B消息在1s到达直接处理就可以 如果超出1s不处理