면책 조항 :이 아마 아주 기본적인 질문이지만, 난 그냥 개념을 이해하고 내가 원하는 것을 달성하기 때문에 드릴 수 없습니다하지 않습니다.asyncio
나는 asyncio 사용하여 기본 에코 클라이언트 서버를 구현하기 위해 노력하고있어. 설명서에 포함 된 샘플부터 시작했습니다. 내가 무엇을 달성하고자하는
는 (어떤이있는 경우) 클라이언트가 즉시 connection_made보다 시간이 다른 에 응답을 읽고 다음 서버에 일부 데이터를 보낼 수있는 영구 연결입니다. 연결은 명시 적으로 닫힐 때까지 양쪽 끝에서 열려 있어야합니다.
나는 프로토콜 샘플로 이것을하고있다. 다른 질문이나 문서를 읽으면서, 이것을 loop.call_later()
을 사용하여 구현할 수있는 것 같지만, 이것은 정말로 좋은 해결책입니까? 이상적으로는 즉시 새 패킷에 응답 할 수 있도록 Queue
을 사용하고 싶습니다.
@asyncio.coroutine
def writer():
global out_queue
while True:
packt = yield from out_queue.get()
print("yeahhh packet yummy")
data = bytes(packt.to_json(), 'ascii')
self.transport.write(data)
asyncio.async(writer())
는 그러나 이것은 아무것도하지 않습니다. 필자는 주 클라이언트 코드에서 새 항목을 삽입하면 즉시 메시지를 출력한다고 가정합니다. 아무것도
또한 디버깅은 큐가 작성되고 표시되지만 out_queue.get() 코 루틴은 반환되지 않습니다 ... 발생하지 않습니다. 초기에 out_queue.put은 항목을 초기 .get() 호출을 위해 웨이터에 거의 직접 배치하지만 마치 루프가 실행 중이 아닌 것처럼 처리합니다. 그것은 전체 클라이언트 연결에 사용되는 동일한 루프입니다. 모든 것을 스레드에 넣었 기 때문에 새 루프를 만들었습니다. 나는 체크했고 .put() 호출로부터 만들어진 적절한 호출은 모두이 루프를위한 것이다.
아, 그냥 경우에 중요한 : 나는 asyncio 핍에 의해 설치와 파이썬 3.3에서이 작업을 실행하고 있습니다.
이def send_packet(loop, queue, packet):
# this runs in main thread, not the loop thread
def f():
print("putting packet into queue")
queue.put_nowait(packet) # MUST NOT use .put() as it's a coroutine
loop.call_soon_threadsafe(f)
# !!! next one doesn't work !!!
# loop.call_soon_threadsafe(any_normal_function_with_coroutine_calls())
print
실행하지 :
업데이트 : 내가 대기열에 항목을 삽입 할 방법이입니다.
글쎄, 실제로 나는 다른 스레드에서 그들을 밀어. 그러나 나는 또한'loop.call_soon_threadsafe() '로 추가 된 함수로부터 푸시하려고 시도했지만 그 함수는 전혀 호출되지 않습니다. – velis
NVM, call_soon_threadsafe를 사용하는 방법에 대한 문서는 특히 명확하지 않습니다. 나는 오래된 함수가 괜찮다고 생각했지만, 그렇지 않다는 것이 밝혀졌습니다. 적절한 해결책으로 업데이트 된 질문 – velis
call_soon, call_later 및 call_soon_threadsafe는 코 루틴이 아닌 일반 함수를 허용합니다. 신선한 asyncio에 대한 검사가 있습니다. –