【问题标题】:Pyro4 does not allow more than two clients to access one URIPyro4 不允许两个以上的客户端访问一个 URI
【发布时间】:2012-09-09 15:55:34
【问题描述】:

我正在使用 pygame 在 Python 中创建一个回合制策略游戏。我发现编写套接字非常困难,所以我求助于 Pyro 来分享游戏板的状态。但是,Pyro 似乎一次无法支持超过 2 个连接。

我正在通过 localhost 在 localhost 上运行名称服务器

python -m Pyro4.naming

测试用例“服务器”:

import Pyro4
class Testcase:
    def __init__(self):
        self.values = [1, 2, 3, 10, 20, 30]

    def askvalue(self, i):
        return self.values[i]


daemon = Pyro4.Daemon()
ns = Pyro4.locateNS()

uri = daemon.register(Testcase())
ns.register("thetest", uri)
daemon.requestLoop()

和客户:

import Pyro4, time

ns = Pyro4.locateNS()

casetester = Pyro4.Proxy("PYRONAME:thetest")

while True:
    print "Accessing remote object:"
    print casetester.askvalue(1)
    print "staying busy"
    time.sleep(10)

前两个客户端的输出:

/usr/local/lib/python2.7/dist-packages/Pyro4-4.14-py2.7.egg/Pyro4/core.py:155: UserWarning: HMAC_KEY not set, protocol data may not be secure
  warnings.warn("HMAC_KEY not set, protocol data may not be secure")
Accessing remote object:
2
staying busy
Accessing remote object:
2
staying busy

然后重复

第三个客户端的输出:

/usr/local/lib/python2.7/dist-packages/Pyro4-4.14-py2.7.egg/Pyro4/core.py:155: UserWarning: HMAC_KEY not set, protocol data may not be secure
  warnings.warn("HMAC_KEY not set, protocol data may not be secure")
Accessing remote object:

然后挂起。

来自第四个、第五个(可能还有更多)客户端的输出:

/usr/local/lib/python2.7/dist-packages/Pyro4-4.14-py2.7.egg/Pyro4/core.py:155: UserWarning: HMAC_KEY not set, protocol data may not be secure
  warnings.warn("HMAC_KEY not set, protocol data may not be secure")

在这个阶段,我给名称服务器一个 ^C,客户端 3、4、...给出这个输出并崩溃:

Traceback (most recent call last):
  File "client.py", line 3, in <module>
    ns = Pyro4.locateNS()
  File "/usr/local/lib/python2.7/dist-packages/Pyro4-4.14-py2.7.egg/Pyro4/naming.py", line 323, in locateNS
    raise Pyro4.errors.NamingError("Failed to locate the nameserver")
Pyro4.errors.NamingError: Failed to locate the nameserver

同时客户端 1 和 2 保持忙碌。

但是,中断其中一个活动客户端将使其中一个挂起的客户端开始运行。

我已经尝试通过“export PYRO_SERVERTYPE = multiplex”来切换线程,但这并没有改变行为。最大连接数的设置似乎是 200。将其设置为 1000 也没有解决我的问题。

我听说 Pyro 缺乏可扩展性,但我肯定能够获得至少 10 个连接吗?

如何一次将两个以上的客户端连接到 Pyro4 对象?

【问题讨论】:

    标签: python concurrency network-programming pyro


    【解决方案1】:

    回答我自己的问题,希望这会很快出现在谷歌上!

    这不是一个“完美”的答案,但它是一个有效的组合。服务器代码保持不变,但客户端代码变为:

    import Pyro4, time
    
    
    global ns
    global casetester
    
    def connect():
        global ns
        global casetester
        ns = Pyro4.locateNS()
        casetester = Pyro4.Proxy("PYRONAME:thetest")
    
    def disconnect():
        global ns
        global casetester
        del ns
        del casetester
    
    
    while True:
        print "Accessing remote object:"
        connect()
        print casetester.askvalue(1)
        disconnect()
        print "staying busy"
        time.sleep(3)
    

    到处都是额外的“全球”,因为从不假设。

    为什么会这样?因为我建立一个连接,访问远程对象,然后删除连接。

    我觉得这个解决方案非常难看,但我会一直使用它,直到找到“正确”的方式。

    【讨论】:

      【解决方案2】:

      我遇到了类似的问题。我独立找到了您的global 解决方案,但它并没有帮助很长时间,随着应用程序规模的增加,该错误又回来了。经过多次尝试和错误,我想我现在可能已经发现了问题......用户错误。

      根据http://pythonhosted.org/Pyro4/nameserver.html,名称服务器本身就是一个代理。所以我确保将它们与“With”语句一起使用,就像我的其他 pyro 代理一样”

      with Pyro4.locateNS() as ns:
        uri = ns.lookup('Object name')
      with Pyro4.proxy(uri) as obj:
        obj.SomeMethod()
      

      对名称服务器的每个引用也执行相同的操作,例如在您的 ns.register('thetest', uri) 调用周围

      【讨论】:

      • 感谢您的想法,一定会尝试。
      【解决方案3】:

      我也有同样的考虑。但是当我和你运行类似的代码时,我发现 Pyro4 (2014-12) 没有这样的问题。

      我测试了 10 个客户端同时调用它。 效果很好。

      我写这篇文章是为了对像我这样的人有用。

      服务器代码

      import Pyro4
      import time
      class Testcase:
          def __init__(self):
              self.value = 1
      
          def askvalue(self, i):
              # Simulate doing some work.
              time.sleep(1)
      
              self.value += 1
              return self.value
      
      
      daemon = Pyro4.Daemon()
      ns = Pyro4.locateNS()
      
      uri = daemon.register(Testcase())
      ns.register("thetest", uri)
      daemon.requestLoop()
      

      客户

      import Pyro4, time
      
      ns = Pyro4.locateNS()
      
      casetester = Pyro4.Proxy("PYRONAME:thetest")
      
      while True:
          print("Accessing remote object:")
          print (casetester.askvalue(1))
          print ("staying busy")
      

      【讨论】:

        猜你喜欢
        • 2013-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-16
        • 1970-01-01
        • 2012-09-07
        • 2017-02-26
        • 1970-01-01
        相关资源
        最近更新 更多