asynchat
---异步套接字命令/响应处理程序¶
源代码: Lib/asynchat.py
3.6 版后已移除: 请使用 asyncio
相反。
注解
此模块仅用于向后兼容。对于新代码,我们建议使用 asyncio
.
本模块建立在 asyncore
基础结构,简化异步客户机和服务器,并使其更容易处理由任意字符串终止或长度可变的协议。 asynchat
定义抽象类 async_chat
子类,提供 collect_incoming_data()
和 found_terminator()
方法。它使用的异步循环与 asyncore
以及两种类型的通道, asyncore.dispatcher
和 asynchat.async_chat
,可以在通道图中自由混合。典型地 asyncore.dispatcher
服务器通道生成新的 asynchat.async_chat
接收传入连接请求时的通道对象。
- class asynchat.async_chat¶
此类是的抽象子类
asyncore.dispatcher
. 要实际使用代码,必须子类async_chat
,提供有意义的collect_incoming_data()
和found_terminator()
方法。这个asyncore.dispatcher
可以使用方法,尽管在消息/响应上下文中并非所有方法都有意义。类似于
asyncore.dispatcher
,async_chat
定义一组事件,这些事件是在select()
调用。一旦启动了轮询循环,async_chat
对象的方法由事件处理框架调用,程序员不执行任何操作。可以修改两个类属性,以提高性能,甚至可能节省内存。
- ac_in_buffer_size¶
异步输入缓冲区大小(默认
4096
)
- ac_out_buffer_size¶
异步输出缓冲区大小(默认
4096
)
不像
asyncore.dispatcher
,async_chat
允许您定义 FIFO 排队 生产者 . 生产者只需要一种方法,more()
,它将返回要在通道上传输的数据。生产者表示精疲力竭。( i.e. 它不包含更多的数据)。more()
方法返回空字节对象。在这一点上async_chat
对象从队列中删除生产者,并开始使用下一个生产者(如果有的话)。当生产者队列为空时,handle_write()
方法不起作用。使用通道对象的set_terminator()
方法描述如何识别来自远程端点的传入传输的结束点或重要断点。建立一个功能
async_chat
子类化您的输入方法collect_incoming_data()
和found_terminator()
必须处理通道异步接收的数据。方法如下所述。
- async_chat.close_when_done()¶
推A
None
到生产者队列。当这个生产者从队列中弹出时,它会导致通道关闭。
- async_chat.collect_incoming_data(data)¶
调用 data 持有任意数量的接收数据。必须重写的默认方法引发
NotImplementedError
例外。
- async_chat.discard_buffers()¶
在紧急情况下,此方法将丢弃输入和/或输出缓冲区以及生产者队列中保存的任何数据。
- async_chat.found_terminator()¶
当传入数据流与由设置的终止条件匹配时调用
set_terminator()
.必须重写的默认方法引发NotImplementedError
例外。缓冲输入数据应通过实例属性可用。
- async_chat.get_terminator()¶
返回通道的当前终止符。
- async_chat.push(data)¶
将数据推送到通道队列以确保其传输。这就是让通道将数据写入网络所需要做的全部工作,尽管可以在更复杂的方案中使用自己的生产者来实现加密和分块,例如。
- async_chat.push_with_producer(producer)¶
获取生产者对象并将其添加到与通道关联的生产者队列。当所有当前推送的生产者都已用尽时,通道将通过调用其
more()
方法并将数据发送到远程端点。
- async_chat.set_terminator(term)¶
设置要在通道上识别的终止条件。
term
可以是三种值类型中的任意一种,对应于处理传入协议数据的三种不同方法。学期
描述
string
会调用
found_terminator()
当在输入流中找到字符串时整数
会调用
found_terminator()
当接收到指定的字符数时None
这个频道一直在收集数据
请注意,在结束符之后的任何数据都可以在结束符之后被通道读取。
found_terminator()
被称为。
异步实例¶
下面的部分示例显示了如何使用 async_chat
.Web服务器可能会创建 http_request_handler
每个传入客户端连接的对象。注意,最初,通道终结符被设置为匹配HTTP头端的空白行,并且标志指示正在读取标头。
读取头之后,如果请求的类型为post(指示输入流中存在更多数据),则 Content-Length:
Header用于设置数字终止符,以从通道中读取正确数量的数据。
这个 handle_request()
在将通道终止符设置为 None
以确保忽略Web客户端发送的任何无关数据。地址:
import asynchat
class 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()