Flask是一個用python開發的網絡應用微框架。
http://docs.jinkan.org/docs/flask/docs.jinkan.org
而flask-SocketIO 爲flask應用提供了一個客戶端與服務器之間低延遲的雙向通信。客戶端應用可以用Javascript,C++,Java,Swift或者其它任意的編程語言的socketio官方庫的客戶端去和服務端創建一個永久的連接。
from flask import Flask, render_template
from flask_socketio import SocketIO
app = Flask(__name__)
app.configp['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
if __name__ == '__main__':
socketio.run(app)
這就是一個簡單的Flask應用。
Flask大量使用裝飾器模式,來將用戶應用中的各種函數裝入Flask框架中。所以學習之前應當對python的裝飾器模式的使用熟練掌握。
例如,下面的裝飾器socketio.on()實現對接收到的消息'message'的監聽,'message'是用戶自定義的一個消息種類的名字。也可以改爲其他名字。重點是收發要是同一種消息。同時message是用戶自定義的數據類。
@socketio.on('message')
def handle_message(message):
print('received message: ' + message)
也可以不使用裝飾器語法,而是使用socketio.on_event()代替裝飾器來進行消息監聽:
def my_function_handler(data):
pass
socketio.on_event('my event', my_function_handler, namespace='/test')
後端的flask-socketio的創建和運行方式如下:
from flask import Flask
from flask_socketio import SocketIO,emit
app = Flask(__name__)
socketio = SocketIO()
socketio.init_app(app)
"""
對app進行一些路由設置
"""
@app.route('/')
def index():
return render_template('test.html')
"""
對socketio進行一些監聽設置
"""
if __name__ == '__main__':
socketio.run(app,debug=True,host='0.0.0.0',port=5000)
#這裏就不再用app.run而用socketio.run了。socketio.run的參數和app.run也都差不多
使用@app.route('/')裝飾器設置路由,@socketio.on設置消息監聽。
命名空間namespace使得客戶端可以在一個相同的socket上多路複用幾個獨立的連接。也就是說,同一個物理機可以開啓多個進程並使用同一個socket連接到服務器,只需要指定不同的命名空間即可。
@scoketio.on('my event', namespace='/test')
def handle_my_custom_namespace_event(json):
print('received json: ' + str(json))
發送消息:
使用send()和emit()發送消息,它們分別用於無名和命名事件。
@socketio.on('message')
def handle_message(message):
send(message, namespace='/chat')
@socketio.on('my event')
def handle_my_custom_event(json):
emit('my response', json, namespace='/chat')
使用emit時可以指定namespace來指定命名空間。
@socketio.on('my event')
def handle_my_custom_event(json):
emit('my response', ('foo', 'bar', json), namespace='/chat')
發送的消息也可以帶有參數'foo'和'bar'。
def ack():
print 'message was received!'
@socketio.on('my event')
def handle_my_custom_event(json):
emit('my response', json, callback=ack)
也可以在發送函數emit()等api中使用回調函數。
@socketio.on('my event')
def handle_my_custom_event(data):
emit('my response', data, broadcast=True)
加入broadcast=True參數可以使得send()和emit()廣播消息,所有客戶端都會收到它。若指定命名空間,則只有連接到命名空間的客戶端會收到消息。
使用room可以實現“羣聊”功能。(略)
from flask_socketio import Namespace, emit
class MyCustomNamespace(Namespace):
def on_connect(self):
pass
def on_disconnect(self):
pass
def on_my_event(self, data):
emit('my_response', data)
socketio.on_namespace(MyCustomNamespace('/test'))
使用基於類的命名空間Namespace可以一次性註冊消息的監聽處理函數,便於管理以及面向對象編程。現在,服務器接收的任何消息都會由on_+消息名爲名字的MyCustomNamespace中的成員函數處理。例如my_event消息會由MyCustomNamespace中的on_my_event處理。
socketIO-client是一個基於python實現的socket.io客戶端庫,這個socket.io原本是一個js的庫(flask_socketio也是),github鏈接:https://github.com/invisibleroads/socketIO-client,它與flask_socketIO的關係是,對於用Flask-SocketIO實現的後端,客戶端需要用SocketIO的官方庫實現,語言不限。https://flask-socketio.readthedocs.io/en/latest/
大致使用就是這些,現在比較好奇的問題是,收發消息的時候需要考慮tcp的多個包接收處理嗎,因爲之前在用Python的twisted的時候用datareceived就需要自己對消息做結尾字符,然後作處理,因爲twisted的datareceived會在每個tcp包到達的時候進行調用。還有就是socketIO有沒有像twisted一樣的對於某一個函數執行延時執行的功能,這個功能真的很強大,在差錯處理上十分有用。
參考:
https://www.jianshu.com/p/0032daa111a0
https://blog.csdn.net/weixin_36380516/article/details/80418354
https://juejin.im/post/5bdad42bf265da392a7e2e0e
更多文章與筆記請關注:微信公衆號:二進制樹