Win32com üzerinden MessageQueue.Peek çalıştıran Python, zaman aşımı nasıl elde edilir?


9

Yeni başlayanlar için, eğer birisi burada yardımcı olabilirse, inanılmazsın demek istiyorum.

Genel Soru

Python programımın MSMQ ile etkileşime girmesi gerekiyor. Temel olarak, kuyrukta hiçbir şey yoksa bir zaman aşımı belirterek bir kuyruğa bakmak istiyorum.

Ancak, en iyi çabalarıma rağmen, daha önce kuyrukta bir değer olmadığında Peek () 'i zaman aşımı aralığını bekletemiyorum. Lütfen bu kodda eksik olanları belirtebilir misiniz?


Mevcut Kodum

İşte benim kod şu anda:

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

Ben koşuyorum: inspect.getfullargspec(queue.Peek)ve olsun:

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={})

Denediğim Şeyler

Bu soru : söylemek ReceiveTimeout=timespansorunumu çözmüyor gibi görünüyor.

Değiştirme pythoncom.Emptyile pythoncom.Missingişe görünmüyor

Bu cevaplanmamış soru benimkine çok benziyor


pythoncom CoWaitForMultipleHandles(Flags, Timeout , Handles )size yardımcı olur mu?
LinPy

Merhaba @LinPy özenle düşünüyor musun? Bu yardımcı olabilir, ancak bir çözüm gibi görünüyor. Zaman aşımı için doğru argümanları nasıl alacağımı merak ediyorumqueue.Peek
Intrastellar Explorer

1
Sadece bir düşünce, ama Python'da bu arayüzden gördüğüm diğer örnekler, zaman aşımı için bir tamsayı (milisaniye cinsinden) kullanırlar. Belki pywin32 TimeSpans'i beklediğiniz gibi kullanmıyor ...
Peter Brittain

@PeterBrittain teşekkür ederim, aslında bu hile yaptı! Yorumunuzu aşağıdaki cevap olarak gönderdim.
Intrastellar Explorer

Yanıtlar:


0

Bu makaleyi göndererek-msmq-messages-python buldum

Makale, msmq kullanarak bir iletinin nasıl gönderileceğini ve alınacağını gösterir. Neden bir paket / bağlantı almadıysam, bağlantıyı kapattıysam neden standart soket bağlantısı sözdizimini kullanamayacağınızı anlamıyorum

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

Yani böyle bir şey çok zor olmamalı. En kötü senaryo, bir değişkenin sıfır olup olmadığını her timeout_time değerini kontrol eden bir evre oluşturur. Sıfır kapatma kuyruğu varsa,> 0 sıfıra ayarlanmışsa ve daha fazla ileti beklenirse hiçbir şey alınmaz. Ayrıca python günlüğü için eşzamansız msmq hakkında bir GitHub buldum. asenkron msmq Bu gerçek dlopes7 msmq iken almak dedi

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}')

İstediğiniz cevap değil, işe yarayacak bir cevap.


Merhaba @MichaelHearn! Birden çok yararlı geçici çözüm sağladığınız için teşekkür ederiz. Bu nedenle, size ödül
veriyorum

Teşekkür ederim! @IntrastellarExplorer
Michael Hearn

0

Orijinal sorunun yorumlarında @PeterBrittain sadece kullanmayı denemenizi önerdi:

zaman aşımı için bir tamsayı (milisaniye cinsinden)

Bunu denemeye başladım ve aslında işe yaradı! Ben floatde işe yarayacak değerler buldum . İşte bazı örnek Python kodu:

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

Teşekkürler @PeterBrittain!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.