Socket.IO
Socket.IO本是一個面向實時web應用的JavaScript庫,現在已經成為擁有眾多語言的Web即時通訊應用框架。
Socket.IO 主要使用WebSocket協議。但是如果需要的話,Socket.io可以回退到幾種其它方法,例如Adobe Flash Sockets,JSONP拉取,或是傳統的AJAX拉取,並且在同時提供完全相
同的接口。盡管它可以被用作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要求客戶端與服務器端 均須使用該框架。
我是一個python 工作者,那實際在python中怎么使用呢?
- 首先要安裝 pip install python-socketio
- 創建服務器
- 方式1 使用多線程多進程模式的WSGI服務器對接(如uWSGI)
-
-
-
-
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)
- python 客戶端
-
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()
-