python3.5 异步协议
python3.5 asyncio Protocol
我想搭建一个聊天demo,但是我收不到服务器端发来的东西,除了第一次启动,谁知道为什么?
来自 https://docs.python.org/3.4/library/asyncio-protocol.html#tcp-echo-client-protocol
的代码
Server.py
import asyncio
class EchoServerClientProtocol(asyncio.Protocol):
def connection_made(self, transport):
peername = transport.get_extra_info('peername')
print('Connection from {}'.format(peername))
self.transport = transport
def data_received(self, data):
message = data.decode()
print('Data received: {!r}'.format(message))
print('Send: {!r}'.format(message))
self.transport.write(data)
loop = asyncio.get_event_loop()
# Each client connection will create a new protocol instance
coro = loop.create_server(EchoServerClientProtocol, '127.0.0.1', 8888)
server = loop.run_until_complete(coro)
# Serve requests until Ctrl+C is pressed
print('Serving on {}'.format(server.sockets[0].getsockname()))
try:
loop.run_forever()
except KeyboardInterrupt:
pass
# Close the server
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()
Client.py
class EchoClientProtocol(asyncio.Protocol):
def __init__(self, message, loop):
self.message = message
self.loop = loop
self.transport = None
def connection_made(self, transport):
self.transport = transport
transport.write(self.message.encode())
print('Data sent: {!r}'.format(self.message))
# while 1:
# message=input('please input the message:')
# transport.write(message.encode())
# print('Data sent: {!r}'.format(message))
def data_received(self, data):
# print('data_received')
print('Data received: {!r}'.format(data.decode()))
while 1:
message = input('please input the message:')
self.transport.write(message.encode())
print('Data sent: {!r}'.format(message))
def connection_lost(self, exc):
print('The server closed the connection')
print('Stop the event loop')
self.loop.stop()
loop = asyncio.get_event_loop()
message = 'Hello World!'
coro = loop.create_connection(lambda: EchoClientProtocol(message, loop),
'127.0.0.1', 8888)
loop.run_until_complete(coro)
loop.run_forever()
loop.close()
结果显示:
无法显示 'Data received: '#####'
比如 'def data_received(self, data)' 只用了一次
有人有解决办法吗?
[结果][1]
[1]: https://i.stack.imgur.com/IoqA9.png
您从 EchoClientProtocol.data_received()
创建了所谓的阻塞函数。只有当事件循环可以处理它但阻止功能阻止它时,来自服务器的每个传递的消息才能传递到 EchoClientProtocol.data_received()
。
这个代码
while 1: # More Pythonic way is While True
message = input('please input the message:')
self.transport.write(message.encode())
从用户获取消息并将其发送到服务器,直到这一刻一切都很好。在下一步中,它开始另一个循环,但代码永远不会进入事件循环(因此无法处理传入的消息)。
您可以像这样编辑客户端代码:
def data_received(self, data):
print('Data received: {!r}'.format(data.decode()))
message = input('please input the message:')
self.transport.write(message.encode())
当您从服务器接收到 Hello World!
时,首先调用客户端中的 data_received
(它是从 connection_made
发送的 Hello World!
)。现在处理如下:
- 它打印收到的消息(在第一次调用时是
Hello World!
)
- 收到用户的新消息
- 发送到服务器
- 函数returns并将控制权交给事件循环。
- 服务器收到新消息并将其发送回客户端
- 客户端调用的事件循环
data_received
- 转到步骤 1
我想搭建一个聊天demo,但是我收不到服务器端发来的东西,除了第一次启动,谁知道为什么? 来自 https://docs.python.org/3.4/library/asyncio-protocol.html#tcp-echo-client-protocol
的代码Server.py
import asyncio
class EchoServerClientProtocol(asyncio.Protocol):
def connection_made(self, transport):
peername = transport.get_extra_info('peername')
print('Connection from {}'.format(peername))
self.transport = transport
def data_received(self, data):
message = data.decode()
print('Data received: {!r}'.format(message))
print('Send: {!r}'.format(message))
self.transport.write(data)
loop = asyncio.get_event_loop()
# Each client connection will create a new protocol instance
coro = loop.create_server(EchoServerClientProtocol, '127.0.0.1', 8888)
server = loop.run_until_complete(coro)
# Serve requests until Ctrl+C is pressed
print('Serving on {}'.format(server.sockets[0].getsockname()))
try:
loop.run_forever()
except KeyboardInterrupt:
pass
# Close the server
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()
Client.py
class EchoClientProtocol(asyncio.Protocol):
def __init__(self, message, loop):
self.message = message
self.loop = loop
self.transport = None
def connection_made(self, transport):
self.transport = transport
transport.write(self.message.encode())
print('Data sent: {!r}'.format(self.message))
# while 1:
# message=input('please input the message:')
# transport.write(message.encode())
# print('Data sent: {!r}'.format(message))
def data_received(self, data):
# print('data_received')
print('Data received: {!r}'.format(data.decode()))
while 1:
message = input('please input the message:')
self.transport.write(message.encode())
print('Data sent: {!r}'.format(message))
def connection_lost(self, exc):
print('The server closed the connection')
print('Stop the event loop')
self.loop.stop()
loop = asyncio.get_event_loop()
message = 'Hello World!'
coro = loop.create_connection(lambda: EchoClientProtocol(message, loop),
'127.0.0.1', 8888)
loop.run_until_complete(coro)
loop.run_forever()
loop.close()
结果显示: 无法显示 'Data received: '#####' 比如 'def data_received(self, data)' 只用了一次 有人有解决办法吗? [结果][1] [1]: https://i.stack.imgur.com/IoqA9.png
您从 EchoClientProtocol.data_received()
创建了所谓的阻塞函数。只有当事件循环可以处理它但阻止功能阻止它时,来自服务器的每个传递的消息才能传递到 EchoClientProtocol.data_received()
。
这个代码
while 1: # More Pythonic way is While True
message = input('please input the message:')
self.transport.write(message.encode())
从用户获取消息并将其发送到服务器,直到这一刻一切都很好。在下一步中,它开始另一个循环,但代码永远不会进入事件循环(因此无法处理传入的消息)。
您可以像这样编辑客户端代码:
def data_received(self, data):
print('Data received: {!r}'.format(data.decode()))
message = input('please input the message:')
self.transport.write(message.encode())
当您从服务器接收到 Hello World!
时,首先调用客户端中的 data_received
(它是从 connection_made
发送的 Hello World!
)。现在处理如下:
- 它打印收到的消息(在第一次调用时是
Hello World!
) - 收到用户的新消息
- 发送到服务器
- 函数returns并将控制权交给事件循环。
- 服务器收到新消息并将其发送回客户端
- 客户端调用的事件循环
data_received
- 转到步骤 1