【问题标题】:Keep Python COM local server listening open in paralallel while the main code runs在主代码运行时保持 Python COM 本地服务器并行监听打开
【发布时间】:2018-11-12 00:01:38
【问题描述】:

我正在尝试构建一个 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()

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

【问题讨论】:

  • 您不应该同时注册和服务,因为pythonw.exe会在请求时启动进程外服务器。所以首先注册你的服务器,然后什么都不做。在此处查看示例:stackoverflow.com/questions/1054849/…
  • @SimonMourier,我已经看过这篇文章了。请注意,Rob 的答案标记为已解决。他解释说 ...register.UseCommandLine() 只注册了一段代码,以便即使在服务器应用程序关闭时也可以访问它。因此,我需要让这个服务器保持运行,因为我需要监听客户端。这就是 ...localserver.serve () 的原因。它有效。问题是当我运行服务器时,其他一切都在等待服务器的进程结束。就在我手动关闭服务器窗口时,上面的代码会打印所有客户端的“语音”。它应该是实时的。
  • 我理解你的问题,我指出这个答案正是因为它解释了如何去做。您不必运行服务器并等待某些东西。您手动运行它仅用于注册和注销。之后,当有人访问它时,它会被pythonw.exe启动。
  • @SimonMourier,是的。你说的对。没有必要... register.UseCommandLine() ...localserver.serve() 做到了。之后,我得到了一个解决方案,重写了 localserver.serve() 函数并在新线程中启动它。

标签: python server com chat localserver


【解决方案1】:

我的问题已经解决了,重写了 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

我还做了一些改进,比如队列,以便稍后获取数据。我希望它可以帮助其他人。

【讨论】:

    猜你喜欢
    • 2019-10-21
    • 2012-04-08
    • 1970-01-01
    • 2021-06-11
    • 1970-01-01
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多