>Lucy got a b'cherry' at 2014-06-03 03:15:13.234785, only 6 left
>Lucy got a b'cherry' at 2014-06-03 03:15:13.736103, only 7 left
>Lucy got a b'caramel' at 2014-06-03 03:15:14.238152, only 9 left
>Lucy got a b'cherry' at 2014-06-03 03:15:14.739561, only 8 left
Бедная Люси.
5. Используйте ZeroMQ, чтобы публиковать стихотворение из упражнения 7 главы 7 по одному слову за раз. Напишите потребителя ZeroMQ, который будет выводить на экран каждое слово, начинающееся с гласной. Напишите другого потребителя, который будет выводить все слова, состоящие из пяти букв. Знаки препинания игнорируйте.
Так выглядит сервер, poem_pub.py, который отщипывает по одному слову стихотворения и публикует его в тему vowels, если оно начинается с гласной, и в тему five, если состоит из пяти букв. Некоторые слова могут оказаться в обеих темах, некоторые — ни в одной:
>import string
>import zmq
>host = '127.0.0.1'
>port = 6789
>ctx = zmq.Context()
>pub = ctx.socket(zmq.PUB)
>pub.bind('tcp://%s:%s' % (host, port))
>with open('mammoth.txt', 'rt') as poem:
>····words = poem.read()
>for word in words.split():
>····word = word.strip(string.punctuation)
>····data = word.encode('utf-8')
>····if word.startswith(('a','e','i','o','u','A','e','i','o','u')):
>········pub.send_multipart([b'vowels', data])
>····if len(word) == 5:
>········pub.send_multipart([b'five', data])
Клиент poem_sub.py подписывается на темы vowels и five и выводит на экран тему и слово:
>import string
>import zmq
>host = '127.0.0.1'
>port = 6789
>ctx = zmq.Context()
>sub = ctx.socket(zmq.SUB)
>sub.connect('tcp://%s:%s' % (host, port))
>sub.setsockopt(zmq.SUBSCRIBE, b'vowels')
>sub.setsockopt(zmq.SUBSCRIBE, b'five')
>while True:
>····topic, word = sub.recv_multipart()
>····print(topic, word)
Если вы запустите эти программы, они не будут работать, хотя код выглядит хорошо. Вам нужно прочитать руководство ZeroMQ, чтобы узнать о проблеме медленного присоединившегося: даже если вы запустите клиент раньше сервера, сервер начнет отправлять данные сразу после запуска, а клиенту потребуется некоторое время, чтобы подключиться к серверу. Если вы публикуете сообщения постоянным потоком и не задумываетесь о том, когда к вам подключаются подписчики, это не проблема. Но в этом случае поток данных настолько короткий, что он заканчивается еще до того, как подписчик успеет моргнуть.
Простейший способ исправить это — заставить публикатора пропустить секунду после вызова метода bind() и до того, как он начнет отправлять сообщения. Назовем эту версию poem_pub_sleep.py:
>import string
>import zmq
>from time import sleep