win32com을 통해 MessageQueue.Peek을 실행하는 Python, 시간 초과를 올바르게 얻는 방법은 무엇입니까?


9

우선, 누군가가 여기서 도울 수 있다면, 당신은 믿을 수 없습니다.

일반적인 질문

내 파이썬 프로그램은 MSMQ와 상호 작용해야합니다. 기본적으로 대기열에 아무것도없는 경우 시간 초과를 지정하여 대기열을 들여다보고 싶습니다.

그러나 최선의 노력에도 불구하고 이전에 대기열에 값이 없으면 Peek ()가 시간 초과 간격을 기다리도록 할 수 없습니다. 이 코드에서 무엇이 빠졌는지 알려 주시겠습니까?


내 현재 코드

여기 내 코드가 있습니다 :

from socket import gethostname

import win32com.client
import pythoncom

import clr
clr.AddReference("System")
clr.AddReference("System.Messaging")
from System import TimeSpan
from System.Messaging import MessageQueue


# Source: [1]
# [1] https://docs.microsoft.com/en-us/previous-versions/windows/desktop/msmq/ms707027%28v%3dvs.85%29
MQ_DENY_NONE = 0x0
MQ_PEEK_ACCESS = 0x1
MQ_SEND_ACCESS = 0x2


# Set up queue
pythoncom.CoInitialize()
qinfo = win32com.client.Dispatch("MSMQ.MSMQQueueInfo")
qinfo.FormatName = f"direct=os:{gethostname()}\\PRIVATE$\\MyQueue"
queue = qinfo.Open(MQ_PEEK_ACCESS, MQ_DENY_NONE)

# Receive a value
timeout_sec = 1.0
timespan = TimeSpan.FromSeconds(timeout_sec)
label, body = "", ""
# TODO: timeout value does not appear working. It never waits when
#  there's no message
if queue.Peek(pythoncom.Empty, pythoncom.Empty, timespan):
    msg = queue.Receive() . # Blocking receive --> remove msg from the queue
    if msg is not None:
        label = msg.Label
        body = msg.Body

나는 실행 inspect.getfullargspec(queue.Peek)하고 얻는다 :

FullArgSpec(args=['self', 'WantDestinationQueue', 'WantBody', 'ReceiveTimeout', 'WantConnectorType'], varargs=None, varkw=None, defaults=(<PyOleMissing object at 0x00000147F5D43BD0>, <PyOleMissing object at 0x00000147F5D43BD0>, <PyOleMissing object at 0x00000147F5D43BD0>, <PyOleMissing object at 0x00000147F5D43BD0>), kwonlyargs=[], kwonlydefaults=None, annotations={})

내가 시도한 것들

이 질문 : 말하는 ReceiveTimeout=timespan것이 내 문제를 해결하지 못하는 것 같습니다.

교체 pythoncom.Empty로하는 것은 pythoncom.Missing작동하지 않는 것

이 답변되지 않은 질문 은 내 것과 매우 유사 해 보입니다.


pythoncom이 CoWaitForMultipleHandles(Flags, Timeout , Handles )도움이 되셨 습니까?
LinPy

안녕하세요 @ LinPy 정교하겠습니까? 도움이 될 수도 있지만 일종의 해결 방법처럼 보입니다. 시간 제한에 적합한 인수를 얻는 방법이 궁금합니다.queue.Peek
Intrastellar Explorer

1
그냥 생각하지만 파이썬 에서이 인터페이스에 대해 본 다른 예제는 단순히 시간 초과에 정수 (밀리 초)를 사용합니다. 아마도 pywin32가 TimeSpans을 예상
Peter Brittain

@PeterBrittain 감사합니다. 실제로 트릭을 수행했습니다! 아래 답변으로 귀하의 의견을 게시했습니다.
Intrastellar Explorer 21

답변:


0

이 기사를 보내는 것은 msmq-messages-python입니다.

이 기사에서는 msmq를 사용하여 메시지를 보내고받는 방법을 보여줍니다. 패킷 / 연결을받지 못하면 연결을 끊을 수있는 표준 소켓 연결 구문을 사용할 수없는 이유를 이해하지 못합니다.

import select
mysocket.setblocking(0)
ready = select.select([mysocket], [], [], timeout_in_seconds)
if ready[0]:
    data = mysocket.recv(4096)

그래서 그런 것이 너무 어렵지 않아야합니다. 최악의 시나리오는 변수가 0인지 아닌지 모든 timeout_time을 검사하는 스레드를 만듭니다. 0 닫기 큐인 경우> 0이 0으로 설정되고 더 많은 메시지를 기다리는 경우 아무것도 수신되지 않습니다. 파이썬 로깅을위한 비동기 msmq에 대한 GitHub도 발견했습니다. 비동기 MSMQ 이 사람은 바로받을 말했다 진정한 동안 dlopes7의 MSMQ

import time
t_end = time.time() + 60 * 15
messages=0
while time.time() < t_end or messages>0:
    msg = queue.Receive()
    messages+=1
    if(time.time() > t_end and messages>0):
        messages=0
        t_end = time.time() + 60 * 15
    print(f'Got Message from {queue_name}: {msg.Label} - {msg.Body}')

당신이 원하는 대답이 아니라 효과가있는 대답입니다.


안녕하세요 @MichaelHearn! 여러 가지 유용한 해결 방법을 제공해 주셔서 감사합니다. 따라서, 나는 당신에게 현상금을 수여합니다 :)
Intrastellar Explorer

감사합니다! @IntrastellarExplorer
Michael Hearn

0

@PeterBrittain은 원래 질문의 의견에서 다음을 사용하도록 제안했습니다.

시간 종료에 대한 정수 (밀리 초)

나는 그것을 시험해 보았습니다. 실제로 효과가있었습니다! 나는 float잘 작동하는 가치를 발견했다 . 다음은 샘플 Python 코드입니다.

timeout_sec = 1.0
queue.Peek(pythoncom.Empty, pythoncom.Empty, timeout_sec * 1000):

@PeterBrittain 감사합니다!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.