4

我一直在寻找有关此问题的解决方案,但没有骰子。

编辑:我没有指出我正在尝试制作聊天服务器。所以人们登录,他们的 id 被附加到一个users和一个listeners列表中。他们开始聊天。但是,当其中一个尝试关闭选项卡或浏览器时,用户将永远不会从两个列表中删除,因此他/她会保持登录状态。

Edit2:我认为上面的编号有点混乱,所以我把脚本中的部分也贴在了底部。

到目前为止,我已经尝试了 on_connection_close() 函数(它永远不会被触发,我不知道为什么),该on_finish()函数(每次finish()调用 a 时都会被触发)所以也不符合要求.

现在我想出了一些涉及该on_finish()功能的解决方案:

  1. 每当调用UpdateHandler类的post()函数时,就会self.done = 0设置。
  2. 就在finish()函数被触发之前,我设置了self.done = 1.
  3. 现在该函数被调用,我在控制台上on_finish()打印它是 1。self.done
  4. 在同一个on_finish()函数中,我做了一个IF self.done = 1语句,正如预期的那样,它返回TRUE和 Tornado 的io_loop.add_timeout参数time.time()+3(以便它休眠 3 秒以确保用户导航到网站内的另一个页面或完全离开网站)和回调最终将被调用。
  5. 3 秒后,我想检查是否self.done仍然等于 1,或者用户是否仍在网站上,那么它肯定是 0。

顺便说一句,服务器每 30 秒完成一次连接,然后向用户发送通知以启动新连接,以便连接永远不会自行超时。当客户端关闭浏览器并且 30 秒长超时到期时,服务器会尝试发送通知,如果客户端仍在我的网站上,那么它将启动一个新连接,从而调用post()我上面提到的 UpdateHandler 类中的函数,从而设置变量self.done回到 0。(这就是为什么我给了io_loop.add_timeout3 秒的余量。)

现在已经解决了,我想继续尝试看看它是如何工作的。我启动服务器并打开浏览器导航到正确的 url 并观察服务器如何响应(通过print在脚本中放置一些语句)。当用户保持连接时,我可以看到在 post() 调用(当时显示self.done = 0)之后它会休眠 3 秒,然后调用回调函数,但是这个打印出来self.done = 1很奇怪。

我知道这不是最有效的方法,但它是我能想出的唯一解决方案,它甚至没有按预期工作。

结论:

我希望有人有一个很好的选择,或者甚至是我的理论中我错过的一点,这会破坏整个事情。我真的很想知道如何让 Tornado 知道客户端关闭浏览器而不等待 30 秒超时完成。也许通过ping开放连接或其他方式。我看了TORNADIO一点,但不太喜欢它。如果可能的话,我想在纯 Tornado 中做到这一点。

我会尽快提交代码,我已经尝试了半个小时来查看“如何格式化”等,但是当我尝试提交我的编辑时,它给出了一个错误。

  • 您的帖子似乎包含未正确格式化为代码的代码。请使用代码工具栏按钮或 CTRL+K 键盘快捷键将所有代码缩进 4 个空格。如需更多编辑帮助,请单击 [?] 工具栏图标。
4

2 回答 2

0

我已经有这个问题 5 - 6 天了,终于发现了问题所在,嗯.. 不完全是,但它已经解决了!我一直在互联网上搜索,但一无所获。我在上面的帖子中说过,我记得几个月前我尝试相同的脚本时它确实有效,但nginx当时我从未提到过使用。我一直在使用 Apache + mod_proxy 苦苦挣扎,但我不知道问题出在哪里,apache但是当我nginx再次尝试时,它就成功了!

如果你有同样的问题(on_connection_close 没有被解雇) "TRY" nginx。也感谢您的帮助@Nikolay。

于 2012-09-23T01:20:43.730 回答
0

有处理选项卡/浏览器关闭事件的on_close()方法。tornado.websocket.WebSocketHandler这是一个例子:

from tornado.websocket import WebSocketHandler

class MyWebsocketHandler(WebSocketHandler):
    ...

    def on_close(self):
        self.application.database.abort()

参考页。

于 2016-09-21T16:57:26.577 回答