Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 当新消息到达时终止先前的autobahn websocket呼叫_Python_Websocket_Twisted_Autobahn - Fatal编程技术网

Python 当新消息到达时终止先前的autobahn websocket呼叫

Python 当新消息到达时终止先前的autobahn websocket呼叫,python,websocket,twisted,autobahn,Python,Websocket,Twisted,Autobahn,我正在设计一个功能,通过websocket提供类似自动完成的搜索结果。当用户输入的速度足够快时,他们以前的查询通常会过时,因为他们已经在请求新的信息 是否有任何方法可以识别何时传入新查询并终止以前的查询?我尝试在传入新消息时检查查询是否正在处理,但新消息似乎只有在上一个查询(我想取消的查询)完成后才被处理。我也很困惑,当有多个用户同时搜索时,这将如何工作 from autobahn.twisted.websocket import WebSocketServerProtocol, WebSock

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

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

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
始终返回no


谢谢

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

另一种方法(例如,如果无法中止搜索)是在计算搜索之前等待几毫秒,同时检查是否有新的搜索进入

根据您的评论进行编辑

你的问题是,你永远不应该阻塞反应堆回路。你需要做的是将你的
main\u搜索
切碎,这样你就可以将控制权返回到反应堆回路

您是否可以执行以下操作:

def resume_search(position):
    #stuff

reactor.callLater(0, resume_search, current_position)
reactor.callLater将安排您的函数在完成“任务”后立即被调用。您应该将反应堆循环视为一个大的
,而True
基本上可以做3件事

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

只要代码继续运行,它就永远不会到达其他两个。因此,当您插入reactor.callLater时,它将运行reactor循环,直到延迟变量(在本例中可以是0)通过。请注意,不能保证它会及时调用您的函数。这是因为很可能有什么东西正在运行(阻塞反应堆)的时间超过了您指定的时间间隔。因此,您应该将reactor.callLater(0,fun)视为“不忙时给我打电话”

问题是,在处理之前收到的消息并发送响应之前,onMessage甚至不会执行。因此,我需要一些方法来允许高速公路在处理其他消息时接受消息。你的第二个想法是一个很好的B计划,但它会减慢为用户提供服务的速度。