Python chạy MessageQueue.Peek qua win32com, làm thế nào để hết thời gian chờ?


9

Để bắt đầu, tôi muốn nói nếu có ai có thể giúp đỡ ở đây, bạn thật không thể tin được.

Câu hỏi chung

Chương trình Python của tôi cần tương tác với MSMQ. Về cơ bản, tôi muốn nhìn trộm hàng đợi, chỉ định thời gian chờ nếu không có gì trong hàng đợi.

Tuy nhiên, bất chấp những nỗ lực tốt nhất của tôi, tôi không thể khiến Peek () chờ đợi khoảng thời gian chờ, khi không có giá trị nào trước đó trong hàng đợi. Bạn có thể vui lòng chỉ ra những gì còn thiếu từ mã này?


Mã hiện tại của tôi

Đây là mã của tôi ngay bây giờ:

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

Tôi chạy: inspect.getfullargspec(queue.Peek)và nhận:

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

Những điều tôi đã thử

Câu hỏi này : nói ReceiveTimeout=timespandường như không giải quyết được vấn đề của tôi.

Thay thế pythoncom.Emptybằng pythoncom.Missingdường như không hoạt động

Câu hỏi chưa được trả lời này có vẻ rất giống với tôi


pythoncom có CoWaitForMultipleHandles(Flags, Timeout , Handles )giúp gì cho bạn không?
LinPy

Xin chào @LinPy bạn có phiền xây dựng không? Nó có thể giúp đỡ, nó có vẻ như một cách giải quyết. Tôi đang tự hỏi làm thế nào để có được args đúng thời gian chờ trênqueue.Peek
Intrastellar Explorer

1
Chỉ là một suy nghĩ, nhưng các ví dụ khác mà tôi đã thấy về giao diện này trong Python chỉ đơn giản là sử dụng một số nguyên (tính bằng mili giây) cho thời gian chờ của chúng. Có thể pywin32 không xử lý TimeSpans theo cách bạn mong đợi ...
Peter Brittain

@PeterBrittain cảm ơn bạn, điều đó thực sự đã lừa! Tôi đăng bình luận của bạn như câu trả lời dưới đây.
Intrastellar Explorer

Câu trả lời:


0

Tôi tìm thấy bài viết này gửi-msmq-tin nhắn-python

Bài viết chỉ cho bạn cách gửi và nhận tin nhắn bằng msmq. Tôi không hiểu tại sao bạn không thể chỉ cần cú pháp kết nối ổ cắm tiêu chuẩn để nói nếu tôi chưa nhận được gói / kết nối thì hãy kết nối lại

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

Vì vậy, một cái gì đó như thế không nên quá khó khăn. Trường hợp xấu nhất tạo ra một luồng kiểm tra mỗi timeout_time nếu một biến có bằng 0 hay không. Nếu không có hàng đợi đóng, không nhận được gì nếu nó> 0 được đặt thành 0 và chờ thêm tin nhắn. Tôi cũng tìm thấy một GitHub về msmq không đồng bộ để ghi nhật ký python. msmq không đồng bộ Điều này chỉ nói nhận được trong khi True 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}')

Không phải câu trả lời bạn muốn mà là một câu trả lời sẽ có hiệu quả.


Xin chào @MichaelHearn! Cảm ơn bạn đã cung cấp nhiều cách giải quyết hữu ích. Như vậy, tôi sẽ trao thưởng cho bạn tiền thưởng :)
Nhà thám hiểm Intrastellar

Cảm ơn bạn! @IntrastellarExplorer
Michael Hearn

0

Trong các nhận xét ban đầu của câu hỏi, @PeterBrittain đề nghị thử chỉ sử dụng:

một số nguyên (tính bằng mili giây) cho thời gian chờ của họ

Tôi đã loanh quanh để thử nó, và thực sự, nó đã hoạt động! Tôi tìm thấy floatcác giá trị để làm việc là tốt. Đây là một số mã Python mẫu:

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

Cảm ơn bạn @PeterBrittain!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.