– 异步套接字命令/响应处理程序 – 网络和进程间通信(Python教程)(参考资料)
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()
methods.Theasyncore.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_chat
object从队列中删除生成器并开始使用下一个生成器(如果有)。当生产者队列为空时,handle_write()
方法什么都不做。你使用频道对象的set_terminator()
方法描述如何识别结束,oran重要的断点,来自远端点的传入传输构建一个功能
async_chat
子类你的输入方法collect_incoming_data()
和found_terminator()
必须处理通道异步接收的数据。方法如下所述
async_chat.
close_when_done
()-
推
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)-
将数据推送到通道的队列以确保其传输。这是让通道将数据写入网络所需要做的全部工作,尽管可以在更多的情况下使用您自己的生产者用于实现加密和分块的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()