python-socketio 文檔翻譯

教程:https://tutorialedge.net/python/python-socket-io-tutorial/

python-socketio 原文地址 ,在google瀏覽器中可以翻譯爲中文去使用。

首先要搞明白幾個問題:

room – The recipient of the message. This can be set to the session ID of a client to address that client’s room, or to any custom room created by the application, If this argument is omitted the event is broadcasted to all connected clients.

說明
1)第一種room是每一個單獨的客戶端都有的。(通過session ID可以找到)
2)第二種是應用程序自己創建的。
在下面這個方法中,如果省略掉room參數,將會自動發送給所有的連接了的客戶端。

send`(*data*, *room=None*, *skip_sid=None*, *namespace=None*, *callback=None*, ***kwargs*)[¶](https://python-socketio.readthedocs.io/en/latest/#socketio.Server.send "Permalink to this definition")

譯文:

Python-socketio實現了一個Python Socket.IO 服務,這個服務可以單獨運行也可以綜合於一個web項目中。下面是一些它的特徵:

1. 對於javascript,Swift,C++,Java以及官方的Socket.IO 客戶端都兼容,以及兼容任何遵循Socket.IO準則的三方客戶端。
2.Python2.7, Python3.3+ 都是支持的非常好。
3.支持非常多的客戶端,甚至是流行的硬件,當使用基於 [asyncio](https://docs.python.org/3/library/asyncio.html) ([sanic](http://sanic.readthedocs.io/) and [aiohttp](http://aiohttp.readthedocs.io/)), [eventlet](http://eventlet.net/) or [gevent](http://gevent.org/).
的異步服務器。在開發和測試中,任意的 `WSGI` 兼容的多線程服務器都可以使用。
4.內置了一個WSGI中間件去結合Socket.IO流量和標準WSGI應用。
5.廣播消息通知所有連接的客戶端,或者分配它們到“房間”。
6.多個服務器是可選支持的,通過messaging queue,比如Redis或者RabbitMQ。
7.可以通過外部的流程去發消息給客戶端,比如Celery workers或者輔助的腳本。
8.基於事件的帶有修飾器的架構去隱藏這個協議的一些細節。
9.支持HTTP長輪詢和WebSocket傳輸協議。
10.支持XHR2和XHR瀏覽器。
11.支持文本和二進制消息。
12.支持gzip和HTTP壓縮。
13.可配置的CORS響應,避免在瀏覽器上出現跨域問題。

什麼是Socket.IO?

Socket.IO是一個基於事件的雙向通訊的傳輸協議(一般是web瀏覽器),和一個服務端。原始的客戶端和服務端組件實現是通過JavaScript寫的。

入門指南

可以使用pip安裝Socket.IO:

pip install python-socketio

下面是一個使用aiohttp框架(只支持Python 3.5+)實現異步IO的 Socket.IO server 簡單的例子:

from aiohttp import web
import socketio

sio = socketio.AsyncServer()
app = web.Application()
sio.attach(app)

async def index(request):
    """Serve the client-side application."""
    with open('index.html') as f:
        return web.Response(text=f.read(), content_type='text/html')

@sio.on('connect', namespace='/chat')
def connect(sid, environ):
    print("connect ", sid)

@sio.on('chat message', namespace='/chat')
async def message(sid, data):
    print("message ", data)
    await sio.emit('reply', room=sid)

@sio.on('disconnect', namespace='/chat')
def disconnect(sid):
    print('disconnect ', sid)

app.router.add_static('/static', 'static')
app.router.add_get('/', index)

if __name__ == '__main__':
    web.run_app(app)

下面是一個類似的例子,但是使用的Flask和Eventlet的例子,兼容Python2.7和3.3+:

import socketio
import eventlet
from flask import Flask, render_template

sio = socketio.Server()
app = Flask(__name__)

@app.route('/')
def index():
    """Serve the client-side application."""
    return render_template('index.html')

@sio.on('connect')
def connect(sid, environ):
    print('connect ', sid)

@sio.on('my message')
def message(sid, data):
    print('message ', data)

@sio.on('disconnect')
def disconnect(sid):
    print('disconnect ', sid)

if __name__ == '__main__':
    # wrap Flask application with socketio's middleware
    app = socketio.Middleware(sio, app)

    # deploy as an eventlet WSGI server
    eventlet.wsgi.server(eventlet.listen(('', 8000)), app)

客戶端應用必須引入 socket.io-client 庫(1.3.5版本以及以上,越高越好)。

每次客戶端連接到服務器的連接事件處理程序調用sid(會話ID)分配給連接和WSGI環境字典。

每次客戶端連接到服務端的 conenct 事件都是由sid(session ID)分配到連接和WSGI環境字典調用的。服務端可以檢查身份認證或者其他的頭部信息去決定是否這個客戶端允許被連接。要想拒絕一個客戶端的連接,這個處理器必須返回 False

當客戶端發送發送一個事件給服務端,相應的事件處理器會被sid和這個信息調用,可以是單個或者多個參數。這個應用可以定義儘量多的如果被需要的可以被事件處理器關聯的事件。一個事件可以通過一個名稱簡單定義。

當一個客戶端連接中斷了,disconnect 事件就被調用,允許應用去執行清理工作。

服務端

Socket.IO 服務端是 socketio.Server 類的實例,他們可以被一個WSGI適用應用程序使用 socketio.Middleware 去合併:

# create a Socket.IO server
sio = socketio.Server()

# wrap WSGI application with socketio's middleware
app = socketio.Middleware(sio, app)

使用 socketio.Server.on() 方法來註冊服務端的事件處理器:

@sio.on('my custom event')
def my_custom_event():
    pass

對於異步服務端來說,事件處理器可以是常規方法,或者是協程:

@sio.on('my custom event')
async def my_custom_event():
    await sio.emit('my reply')

聊天室

因爲Socket.IO是一個雙向的協議,服務端可以在任意時間發送消息給任意的連接到的客戶端。爲了讓它方便去將客戶端定位到組中,應用程序可以將客戶端放入到聊天室中去,然後將消息定位到整個聊天室中。

當客戶端第一次連接,他們是被分配到他們自己的聊天室中,這個聊天是是以session ID(sid 參數會傳遞給所有的事件處理器)命名的。應用可以通過 socketio.Server.enter_room()socketio.Server.leave_room() 自由地去創建聊天室和管理客戶端。客戶端可以在儘量多的房間裏,也可以根據需求儘量頻繁地被拉入拉出聊天室。當他們的連接不在特別的時候,單獨的聊天室將會分配給她它們,應用程序可以自由地增加和移除客戶端從聊天室中,儘管它只要這樣做就會失去定位獨立客戶端的能力。

@sio.on('enter room')
def enter_room(sid, data):
    sio.enter_room(sid, data['room'])

@sio.on('leave room')
def leave_room(sid, data):
    sio.leave_room(sid, data['room'])

socketio.Server.emit() 方法會獲得一個事件名稱,一個可能是 strbyteslistdict 或者 tuple 類型的消息載體。當發送一個 tuple,在其中的元素必須是上面的其他類型。元組中的元素將會被傳遞給客戶端的回調函數爲多個參數。定位一個個人客戶端,客戶端的sid將會被給一個聊天室(假設這個應用沒有修改這些初始的聊天室)。定位所有的連接的客戶端們,這個聊天室參數將會被觸發。

@sio.on('my message')
def message(sid, data):
    print('message ', data)
    sio.emit('my reply', data, room='my room')

通常在聊天室中當廣播一個消息到一個用戶組的時候,發送者是否接受他自己的消息是可選的。soicketio.Server.emit() 方法提供了一個可選的 skip_sid 參數去指定一個想在廣播中跳過的客戶端。

@sio.on('my message')
def message(sid, data):
    print('message ', data)
    sio.emit('my reply', data, room='my room', skip_sid=sid)

Response

當一個客戶端發送一個事件給服務端,它可以選擇提供一個回調方法,當服務端返回一個響應的時候會被觸發。服務端可以便捷地從相應的事件處理器返回它從而提供一個響應。

@sio.on('my event', namespace='/chat')
def my_event_handler(sid, data):
    # handle the message
    return "OK", 123

事件處理器可以返回一個單獨的值,一個帶多個值的元組。這個在客戶端的回調函數將會調用這些返回的值。

Callbacks
回調

服務端可以請求一個響應通過發送一個事件給客戶端。socketio.Server.emit() 方法有一個可選的 callback 參數能夠被設置爲可回調的。當這個參數被傳遞之後,當客戶端返回相應的時候,這個可回調的方法將會被請求。

當廣播給多個客戶端的時候使用回調函數是不被推薦的,因爲回調方法將會被只執行一次。

Namespace
命名空間

Socket.IO 協議支持多個邏輯性連接,所有的多路複用都是在相同的物理連接上。客戶端可以通過給每個連接指定不同的 namespace 從而開多個連接。一個命名空間是由 主機名+端口+路徑名稱構成的。比如,連接到 http://example.com:8000/chat 將會開一個連接到命名空間 /chat

由於分離的不同的session ID(sids),不同的事件處理器,不同的聊天室,每一個命名空間都是獨立的。應用程序使用多個命名空間從而來區分命名空間,是非常重要的。可以參考 socketio.Server 類。

namespace 參數被觸發了,比如設置爲 None 或者 /, 那麼一個默認的命名空間將會被使用。

Class-Based Namespaces

作爲一個基於裝飾器的事件處理器的代替,這個屬於一個命名空間事件處理器可以被創建爲 socketio.Namesapce 的子類:

class MyCustomNamespace(socketio.Namespace):
    def on_connect(self, sid, environ):
        pass

    def on_disconnect(self, sid):
        pass

    def on_my_event(self, sid, data):
        self.emit('my_response', data)

sio.register_namespace(MyCustomNamespace('/test'))

對於基於異步io的服務端,域名空間必須繼承與 socketio.AsyncNamespace, 也可以定義普通的方法或者協程作爲事件處理器:

class MyCustomNamespace(socketio.AsyncNamespace):
    def on_connect(self, sid, environ):
        pass

    def on_disconnect(self, sid):
        pass

    async def on_my_event(self, sid, data):
        await self.emit('my_response', data)

sio.register_namespace(MyCustomNamespace('/test'))

當使用基於類的命名空間的時候,任何被服務端接受的事件將會被分派到一個被事件名稱命名的方法中作爲方法名稱(with the on_pfrefix)。比如:事件 my_event 將會被一個名叫 on_my_event 的方法處理。

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