Кажется, что цикл прерывает генерацию событий внутри методов пространства имен [gevent-socketio]

в течение нескольких дней я безуспешно пытался создать какой-то цикл на стороне сервера, который позволил бы мне периодически обновлять клиент, но похоже, что если вы поместите цикл в метод события сервера, он перестанет генерировать события для клиент автоматически. Я чувствую, что «gevent» (или гринлеты) не допускают такого поведения (только клиенты, браузеры, использующие socket.io, могут периодически отправлять на сервер, а не наоборот). Я ошибаюсь? Как бы вы решили эту проблему? Возможно ли, что если вы сделаете цикл, соединение с клиентом (сокетом) каким-то образом потеряется? Прилагаю небольшой набросок со схемой.

// Client (socket.io) [Javascript]

client = io.connect('/space');
client.on('do_something', function (msg) {
    // Do something.
});
client.on('do_another_thing', function (msg) {
   // Do another thing.
});
client.emit('something', msg);


# Server (gevent-socketio) [Python]

@namespace('/space')
class SpaceNamespace:
    def on_something(msg):
        # This WORKS just fine cause it's out the scope of the loop.
        self.emit('do_another_thing', some_operation(msg))
        # This DOES NOT work.
        while True:
            # Each 3 seconds update the client.
            self.emit('do_something', some_operation(msg))
            time.sleep(3)
            # If you put an ipdb here, you can see like the code
            # is executed, but the browser doesn't receive any
            # event.

Спасибо!


person javidgon    schedule 22.09.2013    source источник
comment
Приводят ли два вызова self.emit (без какого-либо цикла) в методе on_something к тому, что оба работают?   -  person sberry    schedule 22.09.2013
comment
Да, так было до того, как я попытался использовать цикл, и все работало...   -  person javidgon    schedule 22.09.2013
comment
Возможно, стоит попробовать перейти на gevent.sleep(3)   -  person sberry    schedule 22.09.2013
comment
Оно работает :). Большое спасибо. Если хотите, вы можете создать ответ, чтобы я мог проголосовать за него как за правильный.   -  person javidgon    schedule 23.09.2013


Ответы (1)


Вы захотите изменить time.sleep(3) на gevent.sleep(3), что является способом сказать отдельному гринлету спать. Из документов:

gevent.sleep(seconds=0) Поместить текущий гринлет в спящий режим как минимум на несколько секунд.

секунды могут быть указаны как целое число или число с плавающей запятой, если желательны доли секунды. Вызов сна с секундами, равными 0, — это канонический способ выражения кооперативного выхода.

person sberry    schedule 23.09.2013