python下star最高的是https://github.com/miguelgrinberg/python-socketio
是flask作者写的。client server都有了,而且还提供了async版本。但是怎么说呢,用起来有坑!
1文档太简略。
2 它的客户端和服务器端,在win下启动后,都不能及时响应键盘ctrl+C退出。要等很久很久。
而把它包装进Process,然后
p.daemon = True
设置为守护进程,这样主进程退出,就能正常退出了。
以服务器端为例,客户端同理
from multiprocessing import Process
import signal
import sys
import eventlet
import socketio
clients = {}
def run(port):
sio = socketio.Server()
app = socketio.WSGIApp(sio, static_files={
'/': {'content_type': 'text/html', 'filename': 'index.html'}
})
@sio.event
def connect(sid, environ):
print('connect ', sid)
@sio.event
def disconnect(sid):
print('disconnect ', clients[sid])
print('启动服务器', port)
eventlet.wsgi.server(eventlet.listen(('', port)), app)
if __name__ == '__main__':
p=Process(target=run,args=(9090,)) p.daemon = True
p.start()
#p.terminate()
print('主进程启动')
def signal_handler(signal, frame):
print('关闭从进程')
#p.terminate()
print('主进程退出')
sys.exit(0)
signal.signal(signal.SIGINT,signal_handler)
while True:
pass
但是client 属于强退。clietn退出后N久,才回在服务器端显示:
“ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。”
但是,不论客户端还是服务器端,都没有响应到disconnect, 因为根本就不是正常退出的
而且用Process 的方法,还有个问题,就是占用主机CPU,主进程始终在死循环。直接站走1个CPU,太坑了。
解决方法:
客户端用socketIO_client https://github.com/invisibleroads/socketIO-client
from socketIO_client import SocketIO, BaseNamespace
from requests.exceptions import ConnectionError
from ip import get_host_ip
class Namespace(BaseNamespace):
def on_connect(self):
print("I'm connected!")
SocketIO.emit('auth_mobile', {'ip': get_host_ip()})
def on_reconnect(self):
print('[Reconnected]')
def on_disconnect(self):
print("I'm disconnected!")
def run(ip_admin, port):
sio = socketio.Client()
try:
socketIO = SocketIO(ip_admin, port, Namespace, wait_for_connection=False)
socketIO.wait()
except ConnectionError:
print('The server is down. Try again later.')
if __name__ == '__main__':
run(ip_admin, port)
这个可以轻松退出