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)
这个可以轻松退出