首页 > 解决方案 > 在主代码运行时保持 Python COM 本地服务器并行监听打开

问题描述

我正在尝试构建一个 COM 服务器来获取实时信息。问题是在 localserver 打开时所有其他功能都停止了。其余代码仅在本地服务器关闭时运行。

我已经寻找解决方案但尝试多处理失败,不是因为这不起作用,我想是因为我很烂。无论如何,我被困在这一部分。

import pythoncom
import win32com
from win32com.server import localserver
from multiprocessing import Process

class PythonUtilities(object):

    _reg_clsid_      = '{D9C54599-9011-4678-B1EB-A07FD272F0AF}'
    _reg_desc_       = "Change information between programs"
    _reg_progid_     = "Python.LetsTalk"
    _public_attrs_   = ['speech', 'roger']
    _readonly_attrs_ = ['roger']
    _public_methods_ = ['talktome']

    def __init__(self):
        self.roger  = 'roger'
        self.speech = None

    def talktome(self,speech):
        self.speech = speech
        print ('New speech received: ' + self.speech)
        return self.roger

### ___ ###

def runserver(mess):
    print(mess)
    localserver.serve(['{D9C54599-9011-4678-B1EB-A07FD272F0AF}'])

if __name__=='__main__':

     pu = PythonUtilities

     print ("Registering COM Server ")
     win32com.server.register.UseCommandLine(pu)

     # Fine so far.
     # The problem starts here:

     localserver.serve(['{D9C54599-9011-4678-B1EB-A07FD272F0AF}'])

     #... rest of the code waiting for localserver be closed

     # Experiment... Doesnt work:
     #proc = Process(target=runserver, args = ('starting process',))
     #proc.start()
     #proc.join()

重要的是要说从客户端发送的所有消息似乎都正确显示,但只有在我手动关闭本地服务器之后。我想像聊天应用程序一样实时接收它。我的意思是,我想保持本地服务器处于打开状态,并能够处理在其余代码中收到的信息。

标签: pythonservercomchatlocalserver

解决方案


我的问题已解决,重写 localserver.serve() 函数并在新线程中启动它,如下代码所示。

import pythoncom
from win32com.client import Dispatch # to get attributes
from win32com.server import register, factory
from threading import Thread
from queue import Queue

class PythonUtilities(object):

    _reg_clsid_      = '{D9C54599-9011-4678-B1EB-A07FD272F0AF}'
    _reg_desc_       = "Change information between programs"
    _reg_progid_     = "Python.LetsTalk"
    _public_attrs_   = ['speech']
    _public_methods_ = ['talktome']

    queue_speech = Queue()

    def talktome(self,speech):
        self.queue_speech.put(speech)
        print ('New speech received: ' + speech)
        return 'roger'

### ___ ###

# use instead localserver.serve()
def runserver():

    # added - multithread support
    pythoncom.CoInitialize()

    clsids = ['{D9C54599-9011-4678-B1EB-A07FD272F0AF}']

    infos = factory.RegisterClassFactories(clsids)

    # commented - from original localserver.serve() method
    #pythoncom.EnableQuitMessage(win32api.GetCurrentThreadId())  

    pythoncom.CoResumeClassObjects()

    pythoncom.PumpMessages()

    factory.RevokeClassFactories( infos )

    pythoncom.CoUninitialize()

 if __name__=='__main__':

    #use this
    server_thread = Thread(target=runserver) # Process works as well
    server_thread.start()

    #instead this     
    #localserver.serve(['{D9C54599-9011-4678-B1EB-A07FD272F0AF}'])

    #... rest of the code now works in parallel

我也做了一些改进,比如 Queue 以便稍后获取数据。我希望它可以帮助别人。


推荐阅读