新聞中心
asynchat —- 異步套接字指令/響應(yīng)處理程序
源代碼: Lib/asynchat.py

從版本 3.6 開始標(biāo)記為過時(shí),將在版本 3.12 中移除。: The asynchat module is deprecated (see PEP 594 for details). Please use asyncio instead.
備注
該模塊僅為提供向后兼容。我們推薦在新代碼中使用 asyncio 。
此模塊在 asyncore 框架之上構(gòu)建,簡化了異步客戶端和服務(wù)器并使得處理元素為以任意字符串結(jié)束或者為可變長度的協(xié)議更加容易。 asynchat 定義了一個可以由你來子類化的抽象類 async_chat,提供了 collect_incoming_data() 和 found_terminator() 等方法的實(shí)現(xiàn)。 它使用與 asyncore 相同的異步循環(huán),并且可以在通道映射中自由地混合 asyncore.dispatcher 和 asynchat.async_chat 這兩種類型的通道。 一般來說 asyncore.dispatcher 服務(wù)器通道在接收到傳入的連接請求時(shí)會生成新的 asynchat.async_chat 通道對象。
Availability: not Emscripten, not WASI.
This module does not work or is not available on WebAssembly platforms wasm32-emscripten and wasm32-wasi. See WebAssembly platforms for more information.
class asynchat.async_chat
這個類是 asyncore.dispatcher 的抽象子類。 對于實(shí)際使用的代碼你必須子類化 async_chat,提供有意義的 collect_incoming_data() 和 found_terminator() 方法。 asyncore.dispatcher 的方法也可以被使用,但它們在消息/響應(yīng)上下文中并不是全都有意義。
與 asyncore.dispatcher 類似,async_chat 也定義了一組通過對 select() 調(diào)用之后的套接字條件進(jìn)行分析所生成的事件。 一旦啟動輪詢循環(huán) async_chat 對象的方法就會被事件處理框架調(diào)用而無須程序員方面做任何操作。
兩個可被修改的類屬性,用以提升性能,甚至也可能會節(jié)省內(nèi)存。
-
ac_in_buffer_size
異步輸入緩沖區(qū)大小 (默認(rèn)為
4096)。 -
ac_out_buffer_size
異步輸出緩沖區(qū)大小 (默認(rèn)為
4096)。
與 asyncore.dispatcher 不同,async_chat 允許你定義一個 FIFO 隊(duì)列 producers。 其中的生產(chǎn)者只需要一個方法 more(),該方法應(yīng)當(dāng)返回要在通道上傳輸?shù)臄?shù)據(jù)。 生產(chǎn)者通過讓其 more() 方法返回空字節(jié)串對象來表明其處于耗盡狀態(tài) (意即 它已不再包含數(shù)據(jù))。 此時(shí) async_chat 對象會將該生產(chǎn)者從隊(duì)列中移除并開始使用下一個生產(chǎn)者,如果有下一個的話。 當(dāng)生產(chǎn)者隊(duì)列為空時(shí) handle_write() 方法將不執(zhí)行任何操作。 你要使用通道對象的 set_terminator() 方法來描述如何識別來自遠(yuǎn)程端點(diǎn)的入站傳輸?shù)慕Y(jié)束或是重要的中斷點(diǎn)。
要構(gòu)建一個可用的 async_chat 子類,你的輸入方法 collect_incoming_data() 和 found_terminator() 必須要處理通道異步接收的數(shù)據(jù)。 這些參數(shù)的描述見下文。
async_chat.close_when_done()
將 None 推入生產(chǎn)者隊(duì)列。 當(dāng)此生產(chǎn)者被彈出隊(duì)列時(shí)它將導(dǎo)致通道被關(guān)閉。
async_chat.collect_incoming_data(data)
調(diào)用時(shí)附帶 data,其中包含任意數(shù)量的已接收數(shù)據(jù)。 必須被重載的默認(rèn)方法將引發(fā)一個 NotImplementedError 異常。
async_chat.discard_buffers()
在緊急情況下此方法將丟棄輸入和/或輸出緩沖區(qū)以及生產(chǎn)者隊(duì)列中的任何數(shù)據(jù)。
async_chat.found_terminator()
當(dāng)輸入數(shù)據(jù)流能匹配 set_terminator() 所設(shè)定的終結(jié)條件時(shí)會被調(diào)用。 必須被重載的默認(rèn)方法將引發(fā)一個 NotImplementedError 異常。 被緩沖的輸入數(shù)據(jù)應(yīng)當(dāng)可以通過實(shí)例屬性來獲取。
async_chat.get_terminator()
返回通道的當(dāng)前終結(jié)器。
async_chat.push(data)
將數(shù)據(jù)推入通道的隊(duì)列以確保其被傳輸。 要讓通道將數(shù)據(jù)寫到網(wǎng)絡(luò)中你只需要這樣做就足夠了,雖然以更復(fù)雜的方式使用你自己的生產(chǎn)者也是有可能的,例如為了實(shí)現(xiàn)加密和分塊。
async_chat.push_with_producer(producer)
Takes a producer object and adds it to the producer queue associated with the channel. When all currently pushed producers have been exhausted the channel will consume this producer’s data by calling its more() method and send the data to the remote endpoint.
async_chat.set_terminator(term)
設(shè)置可在通道上被識別的終結(jié)條件。 term 可以是三種類型值中的任意一種 ,對應(yīng)于處理入站協(xié)議數(shù)據(jù)的三種不同方式。
|
term |
描述 |
|---|---|
string |
當(dāng)在輸入流中發(fā)現(xiàn)該字符串時(shí)將會調(diào)用 found_terminator() |
integer |
當(dāng)接收到指定數(shù)量的字符時(shí)將會調(diào)用 found_terminator() |
|
通道會不斷地持續(xù)收集數(shù)據(jù) |
請注意終結(jié)器之后的任何數(shù)據(jù)將可在 found_terminator() 被調(diào)用后由通道來讀取。
asynchat 示例
下面的例子片段顯示了如何通過 async_chat 來讀取 HTTP 請求。 Web 服務(wù)器可以為每個入站的客戶端連接創(chuàng)建 http_request_handler 對象。 請注意在初始時(shí)通道終結(jié)器會被設(shè)置為匹配 HTTP 標(biāo)頭末尾的空行,并且會用一個旗標(biāo)來指明標(biāo)頭正在被讀取。
一旦完成了標(biāo)頭的讀取,如果請求類型為 POST (表明輸入流中存在更多的數(shù)據(jù)) 則會使用 Content-Length: 標(biāo)頭來設(shè)置一個數(shù)值終結(jié)器以從通道讀取適當(dāng)數(shù)量的數(shù)據(jù)。
一旦完成了對所有相關(guān)輸入的處理,將會在設(shè)置通道終結(jié)器為 None 以確保忽略掉 Web 客戶端所發(fā)送的任何無關(guān)數(shù)據(jù)之后調(diào)用 handle_request() 方法。
import asynchatclass http_request_handler(asynchat.async_chat):def __init__(self, sock, addr, sessions, log):asynchat.async_chat.__init__(self, sock=sock)self.addr = addrself.sessions = sessionsself.ibuffer = []self.obuffer = b""self.set_terminator(b"\r\n\r\n")self.reading_headers = Trueself.handling = Falseself.cgi_data = Noneself.log = logdef collect_incoming_data(self, data):"""Buffer the data"""self.ibuffer.append(data)def found_terminator(self):if self.reading_headers:self.reading_headers = Falseself.parse_headers(b"".join(self.ibuffer))self.ibuffer = []if self.op.upper() == b"POST":clen = self.headers.getheader("content-length")self.set_terminator(int(clen))else:self.handling = Trueself.set_terminator(None)self.handle_request()elif not self.handling:self.set_terminator(None) # browsers sometimes over-sendself.cgi_data = parse(self.headers, b"".join(self.ibuffer))self.handling = Trueself.ibuffer = []self.handle_request()
網(wǎng)頁標(biāo)題:創(chuàng)新互聯(lián)Python教程:asynchat—-異步套接字指令/響應(yīng)處理程序
URL標(biāo)題:http://fisionsoft.com.cn/article/dphcohi.html


咨詢
建站咨詢
