首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >当新消息到达时,终止先前的autobahn websocket调用

当新消息到达时,终止先前的autobahn websocket调用
EN

Stack Overflow用户
提问于 2015-05-23 14:07:34
回答 1查看 168关注 0票数 2

我正在设计一个功能,通过websocket提供类似于自动完成的搜索结果。当用户键入的速度足够快时,他们以前的查询通常会过时,因为他们已经在请求新的信息。

是否有任何方法来识别新的查询何时传入,并终止先前的查询?当新消息传入时,我试着检查查询是否正在处理,但似乎只有在完成了上一次查询(我想取消的查询)后,才会处理新消息。当同时有多个用户进行搜索时,我也很困惑这是如何工作的。

代码语言:javascript
运行
AI代码解释
复制
from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory
import json
from twisted.internet.defer import Deferred, inlineCallbacks, returnValue

running = 'no'

def main_search(query): # May take up to 400ms to process
    ...


class SearchServerProtocol(WebSocketServerProtocol):

    @inlineCallbacks
    def onMessage(self, payload, isBinary):
        if not isBinary:
            x = json.loads(payload.decode('utf8'))
            global running
            try:
                print running
                running = 'yes'
                res = yield main_search(x['query'])
                running = 'no'
                print x['query']
            except Exception as e:
                print e
                self.sendClose(1000)
            else:
                self.sendMessage(json.dumps(res).encode('utf8'))


if __name__ == '__main__':

    import sys

    from twisted.python import log
    from twisted.internet import reactor

    log.startLogging(sys.stdout)

    factory = WebSocketServerFactory("ws://104.236.31.77:8080", debug=False)
    factory.protocol = SearchServerProtocol

    reactor.listenTCP(8080, factory)
    reactor.run()

print running总是返回否。

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-24 04:58:21

我认为您需要某种表示用户会话(或搜索会话)的上下文对象。在这种情况下,您可以放置一个latestSearchId,它在每次搜索中都会增加。然后可以将searchId参数添加到main_search中。如果您有一个循环或一些可以中止的不同阶段,您可以通过将当前搜索中的searchId与搜索会话的latestSearchId进行比较来测试它是否仍然是最新的。

另一种方法(例如,如果不能中止搜索)可能是在计算搜索之前等待几毫秒,同时检查是否有新的搜索出现。

根据您的评论编辑

你的问题是你永远不应该阻止反应堆回路。你需要做的是把你的main_search切成碎片,这样你就可以把控制返回到反应堆回路。

你能做这样的事情吗?

代码语言:javascript
运行
AI代码解释
复制
def resume_search(position):
    #stuff

reactor.callLater(0, resume_search, current_position)

一旦reactor.callLater完成了它的工作,它就会安排您的函数被调用。你应该把反应堆循环看作是一个大的while True,基本上可以做三件事。

  • 检查输入IO
  • 执行您的东西(这是处理事件)
  • 发送出的IO

只要您的代码继续运行,它将永远不会到达其他两个。因此,当您插入一个reactor.callLater时,它将运行反应堆循环,直到延迟变量(在我们的例子中可以是0)通过为止。请注意,不能保证它会及时调用您的函数。这是因为它很有可能是运行(阻塞反应堆)比你指定的时间间隔更长。所以你应该把这个reactor.callLater(0, fun)看作是“不忙的时候给我打电话”

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30418056

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档