来自发布者的数据进入缓冲区,较慢的订阅者以先进先出的方式逐块读取缓冲区。为了使其充当后进先出(也许这个描述不准确,因为在您的情况下我们只关心最后的数据),您可以使用asynciocreate_datagram_endpoint() 修改 UDP 协议,以便订阅者清除当前缓冲队列并从新队列接收最新数据。
以下是一个示例,我在 macOS 11.4 上使用 Python 3.9.6 进行了测试。
UdpProtocol.py是自定义的UDP协议对象。
import asyncio
class UdpProtocol:
def __init__(self):
self.packets = asyncio.Queue()
def connection_made(self, transport):
print("connection made")
def datagram_received(self, data, addr):
# clear the current queue and the accumulated data
self.packets._queue.clear()
# put latest data to the queue
self.packets.put_nowait((data, addr))
def connection_lost(self, transport):
print("connection lost")
def error_received(self, exc):
pass
async def recvfrom(self):
# get data from the queue
return await self.packets.get()
这是发布者。
import asyncio
from UdpProtocol import UdpProtocol
async def main():
server_address = ("127.0.0.1", 8000)
loop = asyncio.get_running_loop()
transport, protocol = await loop.create_datagram_endpoint(
UdpProtocol, local_addr=None, remote_addr=server_address)
idx = 0
while True:
transport.sendto(str(idx).encode(), server_address)
print(idx)
idx += 1
await asyncio.sleep(0.1)
if __name__ == "__main__":
asyncio.run(main())
这是订阅者。
import asyncio
from UdpProtocol import UdpProtocol
async def main():
server_address = ("127.0.0.1", 8000)
loop = asyncio.get_running_loop()
transport, protocol = await loop.create_datagram_endpoint(
UdpProtocol, local_addr=server_address, remote_addr=None)
while True:
data, addr = await protocol.recvfrom()
print(data, addr)
await asyncio.sleep(1)
if __name__ == "__main__":
asyncio.run(main())