Python Tornado Websocket 连接在关闭后仍然打开 [英] Python Tornado Websocket Connections still open after being closed

查看:31
本文介绍了Python Tornado Websocket 连接在关闭后仍然打开的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Tornado Websocket 服务器,我想在 30 分钟不活动后超时.我使用 self.close() 在 30 分钟不活动后关闭连接.但似乎有些连接即使在关闭后仍保持打开状态.

I have a Tornado Websocket Server and I want to time out after 30 minutes of inactivity. I use self.close() to close the connection after 30 minutes of inactivity. But it seems that some connections stay open even after being closed.

这里是代码的基本部分(从这里获得帮助后实现:如何在 Tornado Websocket 中一段时间​​后自动关闭连接服务器端):

Here the essential part of the code (which is implemented after getting help from here: How to automatically close connection serverside after a certain time in Tornado Websocket):

打开连接:

class WebSocketHandler(tornado.websocket.WebSocketHandler):
    def open(self, *args):
        self.id = self.generate_id()
        self.stream.set_nodelay(True)
        # ... DO STUFF ...
        self.ini_time = datetime.now()
        self.message_number = 0
        self.last_message_time = self.ini_time
        self.write_message("Connection SUCCESSFUL! Thanks for connecting! Your connection ID is: %d :)" % self.id)
        self.timeout = tornado.ioloop.IOLoop.current().add_timeout(timedelta(minutes=30), self.force_close)
        print datetime.now()
        print "New connection. ID: %d" % self.id
        print "Total number of open connections: %d" % len(clients)

收到消息时:

    def on_message(self, message):        
        """
        when we receive some message we want some message handler..
        for this example i will just print message to console
        """
        if self.timeout:
            tornado.ioloop.IOLoop.current().remove_timeout(self.timeout)
        self.timeout = tornado.ioloop.IOLoop.current().add_timeout(timedelta(minutes=30), self.force_close)
        self.last_message_time = datetime.now()
        self.message_number+=1

        print datetime.now()
        print "Client %s sent message : %s" % (self.id, message)
        # ... DO STUFF ...

关闭时:

def on_close(self):
    self.common_close()

def common_close(self):
    print datetime.now()
    print "Open connections are:"
    print clients.keys()
    print "Closing connection %d." % self.id 

    end = datetime.now()
    timeonline = end - self.ini_time
    timeconlastmsg = self.last_message_time - self.ini_time
    print "Total time online:"
    print timeonline
    print "Time between connection start and last message received:"
    print timeconlastmsg
    if self.id in clients.keys():
        del clients[self.id]
    print "Number of open connections: %d" % len(clients)
    print "Open connections are:"
    print clients.keys()

超时:

def force_close(self):
    timout =  datetime.now()
    print timout
    print "Connection %d timed out, server is dropping the connection." % self.id
    self.common_close()
    self.close() 

超时有效,函数 force_close 被调用.但似乎即使在被调用并从 clients 中删除连接后,连接仍然打开并处于活动状态.

The time-out works, and the function force_close gets called. But it seems that even after being called, and deleting the connection from clients the connection is still open and active.

这是程序的输出示例:

New connection. ID: 66919
Total number of open connections: 3
2015-07-14 21:51:48.387892
New connection. ID: 12012
Total number of open connections: 4
2015-07-14 21:51:48.641603
Open connections are:
[66919, 12012, 11281, 97458]
Closing connection 66919.
Total time online:
0:00:00.404316
Time between connection start and last message received:
0:00:00
Number of open connections: 3
Open connections are:
[12012, 11281, 97458]
... ...
Number of open connections: 4
Open connections are:
[66246, 12012, 97458, 6069]
2015-07-14 22:21:47.906129
Connection 97458 timed out, server is dropping the connection.
2015-07-14 22:21:47.906167
Open connections are:
[66246, 12012, 97458, 6069]
Closing connection 97458.
Total time online:
0:30:00.000450
Time between connection start and last message received:
0:00:00
Number of open connections: 3
Open connections are:
[66246, 12012, 6069]
2015-07-14 22:21:48.237407
Connection 66919 timed out, server is dropping the connection.
2015-07-14 22:21:48.237444
Open connections are:
[66246, 12012, 6069]
Closing connection 66919.
Total time online:
0:30:00.000143
Time between connection start and last message received:
0:00:00
Number of open connections: 3

可以看出,66919 以 30 分钟的间隔关闭"了两次.有什么想法吗?

As can be seen, 66919 was "closed" twice at 30 minutes interval. Any ideas?

连接 3358 关闭的另一个示例,当应该没有更多打开的连接时(再次关闭两次,间隔 30 分钟):

Another example of a connection 3358 being closed when there were supposedly no more open connections (again closed twice, at 30 minutes interval):

Open connections are:
[7046, 16287]
2015-07-15 11:01:13.604125
New connection. ID: 3358
Total number of open connections: 3
2015-07-15 11:01:28.429574
Open connections are:
[7046, 3358, 16287]
Closing connection 3358.
Total time online:
0:00:14.825568
Time between connection start and last message received:
0:00:00
Number of open connections: 2
Open connections are:
[7046, 16287]
--
Open connections are:
[]
2015-07-15 11:31:13.629530
Connection 3358 timed out, server is dropping the connection.
2015-07-15 11:31:13.629586
Open connections are:
[]
Closing connection 3358.
Total time online:
0:30:00.025556
Time between connection start and last message received:
0:00:00
Number of open connections: 0
Open connections are:
[]

有人指出我不应该在force_close中调用common_close,因为on_close会被self.close调用(),但 on_close() 不会被 self.close() 调用.

Some people have pointed out that I shouldn't call common_close in force_close because on_close will be called by self.close(), but on_close() doesn't get called by self.close().

推荐答案

common_close 被调用两次,但连接只超时一次.在您的第一个示例中,66919 在 21:51 关闭,因为客户端干净地关闭了连接(通过 on_close),然后由于超时而在 22:21 再次关闭.连接对象即使在关闭后仍然存在.连接未打开;只有超时保持活动状态.如果on_close(或common_close)处于活动状态,您需要删除超时.

common_close is called twice but the connections only time out once. In your first example, 66919 is closed at 21:51 because the client closed the connection cleanly (via on_close), and then again at 22:21 due to timeout. The connection object continues to exist even after it is closed. The connection is not open; only the timeout remains active. You need to remove the timeout in on_close (or common_close) if it is active.

你也应该在open()中开始第一次超时而不是等待on_message(),并且force_close()应该设置self.timeout 为 None.

You should also start the first timeout in open() instead of waiting for on_message(), and force_close() should set self.timeout to None.

自 Tornado 4.1 起 on_close() 将被 self.close() 调用.

Since Tornado 4.1 on_close() will be called by self.close().

这篇关于Python Tornado Websocket 连接在关闭后仍然打开的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆