我从昨天开始使用Pyro4,所以我正在试用官方文档中的教程代码。一切都在本地完美运行,但是当我在不同的机器中调整这些示例时遇到了问题,特别是股票市场的例子。所以这是我在服务器和客户端上的改编代码
====服务器端====
stockmarket.py
from __future__ import print_function
import random
import threading
import time
import Pyro4
class StockMarket(object):
def __init__(self, marketname, symbols):
self.name = marketname
self.symbolmeans = {}
for symbol in symbols:
self.symbolmeans[symbol] = random.uniform(20, 200)
self.aggregators = []
def generate(self):
quotes = {}
for symbol, mean in self.symbolmeans.items():
if random.random() < 0.2:
quotes[symbol] = round(random.normalvariate(mean, 20), 2)
print("new quotes generated for", self.name)
for aggregator in self.aggregators:
aggregator.quotes(self.name, quotes)
def listener(self,aggregator):
print("market {0} adding new aggregator".format(self.name))
self.aggregators.append(aggregator)
def symbols(self):
return list(self.symbolmeans.keys())
def run(self):
def generate_symbols():
while True:
time.sleep(random.random())
self.generate()
thread = threading.Thread(target=generate_symbols)
thread.setDaemon(True)
thread.start()
def main():
nasdaq = StockMarket("NASDAQ", ["AAPL", "CSCO", "MSFT", "GOOG"])
newyork = StockMarket("NYSE", ["IBM", "HPQ", "BP"])
daemon = Pyro4.Daemon("159.8.183.94")
nasdaq_uri = daemon.register(nasdaq, "nasdaq")
newyork_uri = daemon.register(newyork, "newyork")
ns = Pyro4.locateNS()
ns.register("example.stockmarket.nasdaq", nasdaq_uri)
ns.register("example.stockmarket.newyork", newyork_uri)
nasdaq.run()
newyork.run()
print("Stockmarkets running.")
daemon.requestLoop()
if __name__ == "__main__":
main()
aggregator.py
from __future__ import print_function
import Pyro4
class Aggregator(object):
def __init__(self):
self.viewers = {}
self.symbols = []
def add_symbols(self, symbols):
self.symbols.extend(symbols)
def available_symbols(self):
return self.symbols
def view(self, viewer, symbols):
print("aggregator gets a new viewer, for symbols:", symbols)
self.viewers[viewer] = symbols
def quotes(self, market, stockquotes):
print (market)
print (stockquotes)
for symbol, value in stockquotes.items():
for viewer, symbols in self.viewers.items():
if symbol in symbols:
viewer.quote(market, symbol, value)
def main():
aggregator = Aggregator()
daemon = Pyro4.Daemon(host="159.8.183.94")
agg_uri = daemon.register(aggregator, "aggregator")
ns = Pyro4.locateNS()
ns.register("example.stockquote.aggregator", agg_uri)
for market, market_uri in ns.list(prefix="example.stockmarket.").items():
print("joining market", market)
stockmarket = Pyro4.Proxy(market_uri)
stockmarket.listener(aggregator)
aggregator.add_symbols(stockmarket.symbols())
if not aggregator.available_symbols():
raise ValueError("no symbols found! (have you started the stock market first?)")
print("Aggregator running. Symbols:", aggregator.available_symbols())
daemon.requestLoop()
if __name__ == "__main__":
main()
====客户端====
viewer.py
from __future__ import print_function
import sys
import Pyro4
if sys.version_info < (3,0):
input = raw_input
class Viewer(object):
def quote(self, market, symbol, value):
print("{0}.{1}: {2}".format(market, symbol, value))
def main():
viewer = Viewer()
daemon = Pyro4.Daemon()
daemon.register(viewer)
ns = Pyro4.locateNS(host="159.8.183.94", port=8080)
aggregator_uri = ns.lookup("example.stockquote.aggregator")
print ("aggregator uri is ", aggregator_uri)
aggregator = Pyro4.Proxy(aggregator_uri)
print("Available stock symbols:", aggregator.available_symbols())
symbols = input("Enter symbols you want to view (comma separated):")
symbols = [symbol.strip() for symbol in symbols.split(",")]
aggregator.view(viewer, symbols)
print("Viewer listening on symbols", symbols)
daemon.requestLoop()
if __name__ == "__main__":
main()
====我如何运行代码====
在服务器计算机上,我运行以下代码来定义名称服务器
python -m Pyro4.naming --host 159.8.183.94 --port 8080
然后我运行了stockmarket.py和aggregator.py,到目前为止一切都很好。之后,我启动了viewer.py,输入我想看的符号,然后我发现了stockmarket.py的错误
Exception in thread Thread-18:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "stockmarket.py", line 37, in generate_symbols
self.generate()
File "stockmarket.py", line 24, in generate
aggregator.quotes(self.name, quotes)
File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 171, in __call__
return self.__send(self.__name, args, kwargs)
File "/usr/local/lib/python2.7/dist-packages/Pyro4/core.py", line 410, in _pyroInvoke
msg = message.Message.recv(self._pyroConnection, [message.MSG_RESULT], hmac_key=self._pyroHmacKey)
File "/usr/local/lib/python2.7/dist-packages/Pyro4/message.py", line 168, in recv
msg = cls.from_header(connection.recv(cls.header_size))
File "/usr/local/lib/python2.7/dist-packages/Pyro4/socketutil.py", line 448, in recv
return receiveData(self.sock, size)
File "/usr/local/lib/python2.7/dist-packages/Pyro4/socketutil.py", line 182, in receiveData
raise err
ConnectionClosedError: receiving: not enough data
我认为这只是我的代码中的一个小错误,我已经被困在这里几个小时,任何建议或帮助都将非常感激!谢谢!
答案 0 :(得分:0)
发布的代码工作正常,我在我的机器上运行它没有问题。当然,我已经用我机器的主机名替换了你的IP地址。
因此,您的网络设置存在问题,或服务器和客户端计算机上的软件配置存在差异。
要排除网络的任何问题,您是否尝试在同一台计算机(服务器)上运行它?这个问题只与观众有关(意思是:在开始股票市场和聚合器之后,他们是否印刷股票代码而没有错误?)
此外,启用调试日志记录并查看是否可以在Pyro生成的日志中找到任何有用的内容。也许它会指出你的问题。看看http://pythonhosted.org/Pyro4/tipstricks.html#logging
最后 - 您必须提供更多信息,以便能够开始找出可能存在的问题。你在服务器和客户端使用什么操作系统?服务器和客户端上的Python和Pyro版本是什么?等