2014-04-15 4 views
2

Visual Studio 용 NuGet 패키지 인 ZeroMQ를 사용하고 있습니다. 내가 사용하는 버전은 3.0.0-rc1입니다.ZeroMQ에서 소켓 연결 끊기 C#

나는 꽤 오랜 시간 동안 검색을 해왔지만 여전히 내 문제에 대한 "우아한"솔루션을 찾을 수 없었습니다. 서버 (ROUTER) 소켓을 생성하고 기본적으로 소켓에 도착하기 위해 모든 데이터를 기다리고 있습니다. 나는 폴러를 만들고 무한 루프에서 기다리는 것으로 이것을합니다. 내 문제는 응용 프로그램을 종료하려고 할 때 Poll() 호출을 중단하는 방법을 알아 내려고합니다. 그건 그렇고, 아래의 코드는 별도의 스레드에서 수행되고 소켓을 생성하기 위해 스레드에 내 컨텍스트를 전달합니다.

 using (ZmqSocket server = cntxt.CreateSocket(ZeroMQ.SocketType.ROUTER)) 
     { 
      string strSocketAddress = String.Format("tcp://{0}:{1}", strIPAddress, nPort.ToString()); 

      try 
      { 
       server.Linger = TimeSpan.FromMilliseconds(1); ; 

       server.Bind(strSocketAddress); 

       server.ReceiveReady += server_ReceiveReady; 

       ZeroMQ.Poller poller = new Poller(new List<ZmqSocket> {server}); 

       while (true) 
       { 
        poller.Poll(); 
       } 

      } 
      catch (ZmqException zex) 
      { 
       server.Disconnect(strSocketAddress); 

       server.Close(); 

       server.Dispose(); 
      } 
     } 

여기 모두가 예상대로 작동하며 소켓에서 데이터를 수신 할 때마다 이벤트를 수신합니다. 그러나 앱 종료를 원할 때 루프에서 벗어나는 방법을 알 수 없습니다. 설문 조사에 타임 아웃을 걸고 내가 종료한다고 말하는 것에 플래그를 넣을 수 있다는 것을 이해합니다.하지만 그보다 더 나은 해결책이 있기를 바라고 있습니다.

지금 어떤 일이 발생하는지는 내가 종료하고 싶을 때 문맥에서 Terminate를 호출하지만 그 시점에서 응용 프로그램이 중단되어 반환되지 않습니다. 나는 여전히 소켓이 열려 있기 때문에 걸려 있다고 가정합니다. 나는 또한 문맥에서 Terminate를 호출 한 후에 소켓이 종료되어야한다는 사실을 알기 위해 Linger 플래그를 설정하여 읽었습니다.하지만 그런 일은 일어나지 않습니다.

내가 catch 절을 사용하는 이유는 버전 2.0을 사용하고 Dispose()를 컨텍스트에서 호출했을 때 예외가 발생하고 정상적으로 소켓을 제거 할 수 있었기 때문입니다. 버전 3.0에서 더 이상 예외가 발생합니다.

내가 뭔가를 놓친 것인지 궁금한가요? 그리고 메시지를 기다리는 자체 스레드에있는 소켓을 종료하는 "우아한"접근 방법이 있다면?

답변

1

"우아"하지는 않지만 실제로는 동일한 프로세스 (다른 스레드)에서 청취 소켓에 실제로 연결하는 것이므로 "이벤트"를 얻고 그 시점에서 "종료"플래그를 확인하십시오.

원본 이름은 "self-pipe trick"입니다.

+0

Poll() 메서드에서 시간 초과를 설정하고 종료 플래그가 올바른지 확인하는 것과 본질적으로 같은 것입니까? 그냥 자기 파이프 속임수에 머리를 감싼다. 내가 볼 수있는 유일한 차이점은 자체 파이프 트릭을 사용하면 Poll 메서드가 실제로 메시지를받을 때만 반환된다는 것입니다 (자신 또는 실제 클라이언트로부터). 이 올바른지? 대답 할 시간을내어 주셔서 감사합니다. – DanScott0806

+0

네, 맞습니다. 멋진 일은 없어. –