Pyro4 Tutorial, Ошибка на разных машинах: недостаточно данных
Я начал использовать 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
Я думаю, что это всего лишь небольшая ошибка в моем коде, и я застрял здесь на несколько часов, любые предложения или помощь будут очень благодарны!! Спасибо!!
1 ответ
Отправленный код работает нормально, я запускаю его на своей машине без проблем. Конечно, я заменил ваш IP-адрес на имя хоста моей машины.
Так что это проблема настройки вашей сети или различия в конфигурации программного обеспечения на вашем сервере и клиентских компьютерах.
Чтобы исключить какие-либо проблемы с сетью, вы пытались запустить все это на одной машине (сервере)? Проблема только со зрителем (имеется в виду: после запуска только биржи и агрегатора, они печатают биржевые тикеры без ошибок?)
Кроме того, включите ведение журнала отладки и посмотрите, сможете ли вы найти что-нибудь полезное в журналах, которые создает Pyro. Может быть, это укажет вам на проблему. Посмотрите на http://pythonhosted.org/Pyro4/tipstricks.html
Наконец - вам действительно нужно предоставить больше информации, чтобы можно было даже понять, в чем может быть проблема. Какую ОС вы используете на сервере и клиенте? Какие версии Python и Pyro на сервере и клиенте? и т.п.