Python 上使用 time.sleep 的简单 websocket 服务器
simple websocket server on Python using time.sleep
在sendMessage
之前使用time.sleep(1)
时,孔进程停止(甚至其他连接)。
def handleConnected(self):
print self.address, 'connected'
for client in clients:
time.sleep(1)
client.sendMessage(self.address[0] + u' - connected')
服务器:https://github.com/dpallot/simple-websocket-server
如何解决?
您正在使用 sleep and the server which you are using seems to be using select 暂停线程来处理请求而不是线程。因此将无法处理其他请求。
所以你不能使用time.sleep
。
你为什么需要睡觉?你能用其他方法解决吗?
也许你可以使用 threading.Timer()
def sendHello(client):
client.sendMessage("hello, world")
for client in clients:
t = Timer(1.0, lambda: sendHello(client))
t.start() # after 30 seconds, "hello, world" will be printed
这超出了我的想象。您还需要一种方法来取消每个计时器,所以我想您需要将每个 t
保存在列表中并在完成后调用它。
您正在使用的服务器是同步的 "select" 类型服务器。这些服务器使用单个进程和单个线程,它们通过使用 select() 函数有效地等待 I/O 多个套接字连接来实现并发。
select 服务器的优势在于它们可以轻松扩展到大量客户端。缺点是,当服务器调用应用程序处理程序(此服务器的 handleConnected()
、handleMessage()
和 handleClose()
方法时),服务器 blocks它们,这意味着当处理程序 运行 正在挂起服务器时,因为处理程序和服务器 运行 在同一个线程上。服务器在这种类型的体系结构中响应的唯一方法是以这样的方式对处理程序进行编码,使它们能够快速执行需要执行的操作并将控制权返回给服务器。return。
您的 handleConnected
处理函数不适合这种类型的服务器,因为它是一个长 运行ning 函数。此函数将 运行 持续几秒钟(与客户端的数量一样多),因此在此期间服务器将被阻止。
您可以通过为您的长 运行ning 任务创建后台线程来解决此服务器中的限制。这样你的处理程序可以在启动线程后 return 返回服务器。然后服务器将重新获得控制权并继续工作,而后台线程会在内部休眠一秒钟的情况下执行该循环。您必须考虑的唯一问题是,现在您拥有某种自产的多线程服务器,因此您将无法轻松扩展。
您可以考虑的另一个选择是使用不同的服务器架构。例如,基于协程的服务器将在您编写代码时支持您的处理函数。我在此类别中推荐的两个服务器是 eventlet and gevent. The eventlet server comes with native WebSocket support. For gevent you have to install an extension called gevent-websocket.
祝你好运!
在sendMessage
之前使用time.sleep(1)
时,孔进程停止(甚至其他连接)。
def handleConnected(self):
print self.address, 'connected'
for client in clients:
time.sleep(1)
client.sendMessage(self.address[0] + u' - connected')
服务器:https://github.com/dpallot/simple-websocket-server
如何解决?
您正在使用 sleep and the server which you are using seems to be using select 暂停线程来处理请求而不是线程。因此将无法处理其他请求。
所以你不能使用time.sleep
。
你为什么需要睡觉?你能用其他方法解决吗?
也许你可以使用 threading.Timer()
def sendHello(client):
client.sendMessage("hello, world")
for client in clients:
t = Timer(1.0, lambda: sendHello(client))
t.start() # after 30 seconds, "hello, world" will be printed
这超出了我的想象。您还需要一种方法来取消每个计时器,所以我想您需要将每个 t
保存在列表中并在完成后调用它。
您正在使用的服务器是同步的 "select" 类型服务器。这些服务器使用单个进程和单个线程,它们通过使用 select() 函数有效地等待 I/O 多个套接字连接来实现并发。
select 服务器的优势在于它们可以轻松扩展到大量客户端。缺点是,当服务器调用应用程序处理程序(此服务器的 handleConnected()
、handleMessage()
和 handleClose()
方法时),服务器 blocks它们,这意味着当处理程序 运行 正在挂起服务器时,因为处理程序和服务器 运行 在同一个线程上。服务器在这种类型的体系结构中响应的唯一方法是以这样的方式对处理程序进行编码,使它们能够快速执行需要执行的操作并将控制权返回给服务器。return。
您的 handleConnected
处理函数不适合这种类型的服务器,因为它是一个长 运行ning 函数。此函数将 运行 持续几秒钟(与客户端的数量一样多),因此在此期间服务器将被阻止。
您可以通过为您的长 运行ning 任务创建后台线程来解决此服务器中的限制。这样你的处理程序可以在启动线程后 return 返回服务器。然后服务器将重新获得控制权并继续工作,而后台线程会在内部休眠一秒钟的情况下执行该循环。您必须考虑的唯一问题是,现在您拥有某种自产的多线程服务器,因此您将无法轻松扩展。
您可以考虑的另一个选择是使用不同的服务器架构。例如,基于协程的服务器将在您编写代码时支持您的处理函数。我在此类别中推荐的两个服务器是 eventlet and gevent. The eventlet server comes with native WebSocket support. For gevent you have to install an extension called gevent-websocket.
祝你好运!