我有一个问题,我希望通过写这个问题来解决,但如果没有,我会发帖看看是否有人可以提供帮助。
我正在使用客户端库(我觉得写得不好)与实时聊天服务器交互,该服务器使用 COMET 风格的 HTTP 长轮询。在某些情况下,我在取消长轮询时遇到问题,我怀疑我可能需要添加一些并发处理代码,但由于以下原因,我发现很难找到最佳方法。
订阅代码(启动长轮询)被实现为一个大循环,具有以下内容
doLongPoll()
{
while(true)
}
//IF channel field boolean unsubscribe == TRUE, if so BREAK;
//perform GET request (and store channel HTTPClient used for this call)
//remove HTTPClient used for this call
//IF channel field boolean unsubscribe == true, if so BREAK;
//IF connection problem sleep(1500) then CONTINUE
//post received data to listeners
}
}
取消订阅调用(将在另一个线程上调用)
unsubscribe()
{
//set channel field boolean unsubscribe == FALSE
//get channel HTTPClient and shutdown
}
我已经隔离了操作交错的问题案例。对我来说,这似乎是代码是多线程的并且客户端代码不是线程安全的结果。管理不善和不重用httpClient
也无济于事。
我遇到的问题之一是取消订阅调用不会阻止下一个 getRequest 发生。
THREAD 1 (polling) THREAD 2
-------- --------
do unsubscribe check (pass)
unsubscribe called
set unsubscribe = true
check if httpClient saved (none)
perform getRequest (save HttpClient first)
我想知道人们认为解决这个问题的最佳方法是什么(时间也有限,所以我不能重写太多代码!)
为了解决这个问题,我认为我可以使用从线程 1 的第一次取消订阅检查到在执行实际获取请求之前保存的同步块,并使用相同的锁同步取消订阅方法。httpClient
目前这是不切实际的,因为提到的第一个同步块将在一个方法调用中开始并在方法调用链的下游完成(由于 lib 的编写方式)——这感觉非常错误,因此需要进行一些重构。
或者我可以只为每个通道而不是每个请求创建一个httpClient
,然后它总是可以关闭,我可能会忽略同步(我认为)。
或者如下所示,我可以将中断用于相同目的
欢迎任何建议 - 如果我有任何进展,我会编辑!
谢谢