Socket.IOpython
Socket.IO本是一個面向實時web應用的JavaScript庫,如今已經成爲擁有衆多語言的Web即時通信應用框架。程序員
Socket.IO 主要使用WebSocket協議。可是若是須要的話,Socket.io能夠回退到幾種其它方法,例如Adobe Flash Sockets,JSONP拉取,或是傳統的AJAX拉取,而且在同時提供徹底相web
同的接口。儘管它能夠被用做WebSocket的包裝庫,它仍是提供了許多其它功能,好比廣播至多個套接字,存儲與不一樣客戶有關的數據,和異步IO操做。後端
Socket.IO 不等價於 WebSocket,WebSocket只是Socket.IO實現即時通信的其中一種技術依賴,並且Socket.IO還在實現WebSocket協議時作了一些調整。服務器
Socket.IO 會自動選擇合適雙向通訊協議,僅僅須要程序員對套接字的概念有所瞭解。多線程
有Python庫的實現,能夠在Python實現的Web應用中去實現IM後臺服務。併發
Socket.io並非一個基本的、獨立的、可以回退到其它實時協議的WebSocket庫,它其實是一個依賴於其它實時傳輸協議的自定義實時傳輸協議的實現。該協議的協商部分使得支持標 準WebSocket的客戶端不能直接鏈接到Socket.io服務器,而且支持Socket.io的客戶端也不能與非Socket.io框架的WebSocket或Comet服務器通訊。於是,Socket.io要求客戶端與服務器端 均須使用該框架。app
我是一個python 工做者,那實際在python中怎麼使用呢?框架
import socketio # create a Socket.IO servers sio = socketio.Server() # 打包成WSGI應用,可使用WSGI服務器託管運行 app = socketio.WSGIApp(sio) # Flask Django
建立好的app對象後,使用uWSGI服務器運行此對象。異步
2. 方式2 做爲Flask、Django應用中的一部分
from wsgi import app # a Flask, Django, etc. application import socketio # create a Socket.IO server sio = socketio.Server() app = socketio.WSGIApp(sio, app)
建立好App 對象,使用uWSGI服務器運行此對象。
3. 方式3 使用協程的方式運行(推薦)
import eventlet eventlet.monkey_patch() import socketio import eventlet.wsgi sio = socketio.Server(async_mode='eventlet') # 指明在evenlet模式下 app = socketio.Middleware(sio) eventlet.wsgi.server(eventlet.listen(('', 8000)), app)
3. 說明:
由於服務器與客戶端進行即時通信時,會盡量的使用長鏈接,因此若服務器採用多進程或多線程方式運行,受限於服務器能建立的進程或者線程數,可以支持的併發鏈接數據端不會很高,也就是服務器性能有限。採用協程的方式運行服務器,能夠提高即時通信服務器的性能。
4 . 事件處理
不一樣於HTTP 服務器的編寫方式,SocketIO服務器編寫再也不以請求Request 和響應Response來處理,而是對收發的數據以數據以消息(message)來對待,收發的不一樣類別消息數據又以事件來區分。
本來HTTP服務的編寫中處理請求,構造響應的視圖處理函數在SocketIO 服務器中修改成收發不一樣的事件的事件處理函數。
@sio.on('connect') def on_connect(sid, environ): """ 與客戶端創建好鏈接後被執行 :param sid: string sid是socketio爲當前鏈接客戶端生成的識別id :param environ: dict 在鏈接握手時客戶端發送的握手數據(HTTP報文解析以後的字典) """ pass @sio.on('disconnect') def on_disconnect(sid): """ 與客戶端斷開鏈接後被執行 :param sid: string sid是斷開鏈接的客戶端id """ pass # 以字符串的形式表示一個自定義事件,事件的定義由先後端約定 @sio.on('my custom event') def my_custom_event(sid, data): """ 自定義事件消息的處理方法 :param sid: string sid是發送此事件消息的客戶端id :param data: data是客戶端發送的消息數據 """ pass
注意
connect 爲特殊事件,當客戶鏈接後自動執行
disconnect 爲特殊事件,當客戶端斷開後自動執行
connect、disconnect 與自定義事件處理方法的函數傳入參數不一樣
羣發
sio.emit('my event', {'data': 'foobar'})
給指定用戶發
sio.emit('my event', {'data': 'foobar'}, room=user_sid)
給一組用戶發
SocketIO提供了房間(room)來爲客戶端分組
sio.enter_room(sid, room_name)
將鏈接的客戶端添加到一個room
@sio.on('chat') def begin_chat(sid): sio.enter_room(sid, 'chat_users')
注意:當客戶端鏈接後,socketio會自動將客戶端添加到以此客戶端sid爲名的room中
sio.leave_room(sid, room_name)
將客戶端從一個room中移除
@sio.on('exit_chat') def exit_chat(sid): sio.leave_room(sid, 'chat_users')
sio.rooms(sid)
查詢sid客戶端所在的全部房間
給一組用戶發送消息的示例
@sio.on('my message') def message(sid, data): sio.emit('my reply', data, room='chat_users')
也可在羣組發消息時跳過指定客戶端
@sio.on('my message') def message(sid, data): sio.emit('my reply', data, room='chat_users', skip_sid=sid)
使用send
發送message
事件消息
對於'message'事件,可使用send方法
sio.send({'data': 'foobar'}) sio.send({'data': 'foobar'}, room=user_sid)
import socketio sio = socketio.Client() @sio.on('connect') def on_connect(): pass @sio.on('event') def on_event(data): pass sio.connect('http://10.211.55.7:8000') sio.wait()