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,太坑了。
解決方法:
sio = socketio.Client() @sio.event def connect(): print("I'm connected!") sio.emit('auth_mobile', {'ip': get_host_ip(), 'hardware': hardware_info}) @sio.event def disconnect(): print("I'm disconnected!") try: sio.connect(f'http://{ip_admin}:{port}') #sio.wait() except socketio.exceptions.ConnectionError: print('連接admin失敗')
不使用sio.wait()
就可以正常退出了,而且暫時沒發現問題
