2011-09-20 4 views
3

LineReceiver 프로토콜을 구현하는 트위스트 서버가 있습니다. 클라이언트 메시지에 대한 응답으로 sendLine을 호출하면 예상대로 회선을 클라이언트에 즉시 씁니다.트위스터 서버가 주도권을 가짐

하지만 클라이언트가 서버에 오랜 계산을 요청합니다. 서버가 주기적으로 진행 메시지를 클라이언트에 보내길 원합니다. 서버가 주도권을 갖고 클라이언트가 아무 것도 요구하지 않고 sendLine을 호출하면 클라이언트가 아무것도 보내지 전에 서버에 메시지를 보낼 때까지 기다리는 것 같습니다.

클라이언트가 명시 적으로 요청하지 않고 서버에서 클라이언트로 즉시 메시지를 보내려면 어떻게해야합니까?

+0

'reactor.callInThread'를 사용할 때만 별도의 스레드에서 실행되는 함수/메소드임을 명심하십시오. 콜백 및 오류도 발생합니다. 모든 것은 기본적으로 원자로 실에서 작동합니다. 코드에서 누가 - 호출 - 사람 관계를 설명하는 것이 도움이 될 수 있습니다. – wberry

+1

서버를 "주도권을 잡으세요": Skynet의 모든 것들이 어떻게 시작 되었습니까? – tsimbalar

답변

2

계산을 비동기 적으로 수행하는 경우 지연을 사용하십시오.
다른 방법으로는 별도의 스레드에서 오랜 계산을 할 수 있습니다. deferrToThread()는 reactor.callFromThread()를 사용합니다.
(주 루프에서는 무거운 계산을하지 않는다고 가정합니다.) 작은 예 :

def some_long_foo(data_array, protocol): 
    def send_msg(msg, protocol): 
     # It actually looks petter in classes without pushing protocol here and 
     # there 
     protocol.transport.write(msg) 

    for n, chunk in enumerate(data_array): 
     do_something_cool(chunk) 
     if n and (n % 10 == 0): 
      from twisted.internet import reactor 
      # here send_msg will be safely executed in main reactor loop 
      reactor.callFromThread(send_msg, '10 more chunks processed', 
            protocol) 

# Somwhere in lineReceived we start long calculation 
def cb(result): 
    self.transport.write('got result: {}'.format(result)) 
d = threads.deferToThread(some_long_foo, data_array, self) 
d.addCallback(cb) 

따라서 이제 우리는 모든 데이터 (10 개) 덩어리 처리에 대해 클라이언트를 알려드립니다 다음 마지막으로 그 결과를 보냅니다. 코드가 정확하지 않을 수 있습니다.

docs

는 UPD : 단지 설명을위한 : 는 sendLine 부분을 놓쳤다. 일반적으로 문제가되지 않습니다. transport.write()

0

"즉시"라고 말하면 "클라이언트가 연결될 때"라고 말하면 LineReceiver 서브 클래스의 connectionMade에서 sendLine을 호출 해보십시오.

+0

nope. 나는 클라이언트가 연결 한 후 어딘가에서 완전히 임의의 시간에 의미합니다. 나는 응답하기 전에 항상 클라이언트가 뭔가를 (연결, 메시지 보내기, ...) 할 때까지 기다리는 느낌이 들었다. 내 질문에 대해 좀 더 명확히하려고 노력할 것이다. –

1

원하는 경우 언제든지 sendLine을 사용하여 회선을 보낼 수 있지만 즉시 도착해야하지만 서버 차단과 관련된 문제가있을 수 있습니다.

sendLine에 대한 호출이 지연됩니다 당신이 처리 한 무리의 중간에 전화를 걸 경우 메시지가 , 원자로 인터럽트를 수신 할 때, 그 다음 잠시 동안 조치가 취해되지 않고 있다는 가능성 등 처리를 수신하고, 메시지를 수신하고, 처리로 돌아 가기 전에 송신 된 대기중인 메시지를 얻습니다. 여기서 다른 답변을 읽고 처리가 메인 스레드를 막지 않는지 확인해야합니다.

관련 문제