【python:flask-SocketIO】網絡通信框架簡單瞭解

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://pycntech.github.io/flask-SocketIO%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91-%E8%81%AA%E8%81%AA.html

https://juejin.im/post/5bdad42bf265da392a7e2e0e

 

更多文章與筆記請關注:微信公衆號:二進制樹

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章