3

pygameを使用してPythonでターン制ストラテジーゲームを作成しています。ソケットを書くのは非常に難しいと思ったので、ゲームボードの状態を共有するためにPyroに頼りました。ただし、Pyroは一度に2つ以上の接続をサポートできないようです。

ローカルホストでネームサーバーを実行しています

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)

最初の2つのクライアントからの出力:

/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

繰り返します

3番目のクライアントからの出力:

/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:

とハングします。

4番目、5番目(そしておそらくそれ以降)のクライアントからの出力:

/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はビジー状態のままです。

ただし、アクティブなクライアントの1つを切断すると、ハングしたクライアントの1つが動作を開始します。

「exportPYRO_SERVERTYPE=multiplex」を使用してスレッドから切り替えようとしましたが、動作は変わりませんでした。最大接続数の設定は200のようです。1000に設定しても問題は解決しませんでした。

Pyroにはスケーラビリティがないことを読みましたが、少なくとも10の接続に到達できることは確かですか?

一度に3つ以上のクライアントをPyro4オブジェクトに接続するにはどうすればよいですか?

4

3 に答える 3

2

私自身の質問に答えて、うまくいけば、これはグーグルに迅速に表示されます!

これは「完璧な」答えではありませんが、実用的な恨みです。サーバーコードは同じままですが、クライアントコードは次のようになります。

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)

決して想定しないので、いたるところに余分な「グローバル」。

なぜこれが機能するのですか?接続しているので、リモートオブジェクトにアクセスしてから、接続を削除します。

この解決策は非常に醜いですが、「正しい」方法が見つかるまで使用します。

于 2012-09-10T16:38:13.670 に答える
1

私も同様の問題を抱えていました。私は独自にあなたのglobal解決策を見つけましたが、それは長い間役に立ちませんでした、アプリケーションの規模が大きくなるにつれてバグが戻ってきました。多くの試行錯誤の末、私は今問題を見つけたかもしれないと思います...ユーザーエラー。

http://pythonhosted.org/Pyro4/nameserver.htmlによると、ネームサーバー自体はプロキシです。そのため、他のパイロプロキシと同じように「With」ステートメントでそれらを使用するようにしました。

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

ns.register('thetest', uri)また、呼び出しの周りのように、ネームサーバーへのすべての参照で同じことを行います

于 2013-05-30T12:09:38.073 に答える
0

私はまったく同じ考えを持っています。しかし、私があなたと同様のコードを実行したとき、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")
于 2014-12-08T01:40:41.620 に答える