asynchat异步接字命令/响应处理程序

源代码: Lib / asynchat.py

自版本3.6以后不推荐使用:请使用asyncio而不是


注意

此模块仅用于向后兼容。对于新代码推荐使用asyncio.

这个模块建立在asyncore基础结构,简化异步客户端和服务器,并使处理协议的协议更容易,这些协议的元素由任意字符串终止,或者长度可变.asynchat定义了你的子类的抽象类async_chat,提供了collect_incoming_data()found_terminator()方法的实现。它使用与asyncore相同的异步循环,以及两种类型的通道asyncore.dispatcherasynchat.async_chat,可以在频道图中自由混合。通常是asyncore.dispatcher服务器频道生成新的asynchat.async_chat收到传入连接请求时的通道对象.

class asynchat.async_chat

这个类是asyncore.dispatcher。为了实际使用代码,你必须继承async_chat,提供有意义的collect_incoming_data()found_terminator()methods.The asyncore.dispatcher可以使用方法,虽然不是所有makesense在消息/响应上下文中.

Like asyncore.dispatcher, async_chat定义了一组事件,这些事件是在select()之后通过分析套接字条件生成的呼叫。一旦启动了轮询循环,async_chat对象的方法由事件处理框架调用,程序员无需任何操作.

可以修改两个类属性,以提高性能,或者甚至可以节省内存.

ac_in_buffer_size

异步输入缓冲区大小(默认4096).

ac_out_buffer_size

异步输出缓冲区大小(默认4096).

asyncore.dispatcher, async_chat不同,允许你定义的队列producers。生产者只需要一个方法,more(),它应该返回数据以便在通道上传输。生产者通过其i.e.表示耗尽(more()它不包含更多数据)方法返回空字节对象。此时async_chatobject从队列中删除生成器并开始使用下一个生成器(如果有)。当生产者队列为空时,handle_write()方法什么都不做。你使用频道对象的set_terminator()方法描述如何识别结束,oran重要的断点,来自远端点的传入传输

构建一个功能async_chat子类你的输入方法collect_incoming_data()found_terminator()必须处理通道异步接收的数据。方法如下所述

async_chat.close_when_done

None到生产者队列。当这个生产者从队列中弹出时会导致频道关闭.

async_chat.collect_incoming_datadata

data持有任意数量的接收数据。默认方法,必须被覆盖,提出一个NotImplementedError例外

async_chat.discard_buffers// ()

在紧急情况下,此方法将丢弃输入和/或输出缓冲区和生产者队列中保存的任何数据.

async_chat.found_terminator ( )

当传入数据流匹配由set_terminator()设置的终止条件时调用。必须覆盖的默认方法会引发NotImplementedError异常。缓冲输入数据可以通过实例属性获得.

async_chat.get_terminator)

返回通道的当前终结器.

async_chat.pushdata

将数据推送到通道的队列以确保其传输。这是让通道将数据写入网络所需要做的全部工作,尽管可以在更多的情况下使用您自己的生产者用于实现加密和分块的complexschemes,例如.

async_chat.push_with_producer (producer

生成一个生成器对象并将其添加到与该通道关联的生成器队列中。当所有当前推送的生产者都已经筋疲力尽时,通道会通过调用它的more()方法来消耗这个生产者的数据并将数据发送到远程端点.

async_chat.set_terminator (term )

设置要在通道上识别的终止条件。term可以是三种类型的值中的任何一种,对应于处理传入协议数据的三种不同方式.

术语 描述
string 将会通知 found_terminator()当在输入流中找到thestring时
integer 当收到指定数量的字符时会调用found_terminator()
None 频道继续收集数据

请注意,调用found_terminator()后,终结器后面的任何数据都可以通过通道读取.

asynchat示例

以下部分示例显示了如何使用async_chat读取HTTP请求。Web服务器可能会创建一个http_request_handler每个传入客户端连接的对象。通知最初将通道终结器设置为匹配HTTP标头末尾的空行,并且标志指示标题正在读取.

一旦读取了标题,如果请求是POST类型(表示输入流中存在更多数据),那么Content-Length:header用于设置数字终结器以从通道读取数据量

// handle_request()在将通道终止符设置为None之后,一旦所有相关输入被编组,就会调用该方法,以确保忽略Web客户端发送的任何无关数据.

import asynchatclass http_request_handler(asynchat.async_chat):    def __init__(self, sock, addr, sessions, log):        asynchat.async_chat.__init__(self, sock=sock)        self.addr = addr        self.sessions = sessions        self.ibuffer = []        self.obuffer = b""        self.set_terminator(b"\r\n\r\n")        self.reading_headers = True        self.handling = False        self.cgi_data = None        self.log = log    def collect_incoming_data(self, data):        """Buffer the data"""        self.ibuffer.append(data)    def found_terminator(self):        if self.reading_headers:            self.reading_headers = False            self.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 = True                self.set_terminator(None)                self.handle_request()        elif not self.handling:            self.set_terminator(None)  # browsers sometimes over-send            self.cgi_data = parse(self.headers, b"".join(self.ibuffer))            self.handling = True            self.ibuffer = []            self.handle_request()