Как я могу отправить сообщение из маршрута фляги в сокет с помощью flask-socketio

У меня есть следующий сценарий, который я хотел бы реализовать:

  • Пользователи переходят на наш сайт
  • Пользователь вводит биткойн-адрес.
  • На сервер создается веб-сокет, передающий адрес.
  • Сервер регистрирует обратный вызов с помощью Blocktrail
  • Когда срабатывает обратный вызов (платеж был замечен Blocktrail), мы отправляем сообщение обратно в браузер.
  • Страница, которую просматривает пользователь, обновляется, чтобы показать полученное сообщение.

Я использую веб-перехватчики из API Blocktrail, чтобы «прослушивать» событие, являющееся прием монет на адрес.

Теперь, когда событие происходит, API выполняет POST для моего URL-адреса. Это должно отправить сообщение в браузер, который подключен к моему серверу с помощью socket.io (например, «платеж виден на блокчейне»).

Итак, вопрос в том,

Как я могу отправить сообщение из маршрута в сокет с помощью flask-socketio

Псевдокод:

@app.route('/callback/<address>')
def callback(id):
    socketio.send('payment seen on blockchain')

@socketio.on('address',address)
def socketlisten(address):
    registerCallback(address)

person Dennis Decoene    schedule 08.10.2015    source источник
comment
Не могли бы вы немного подробнее описать, как, что и в каком порядке что-то должно происходить. Также можно изучить этот stackoverflow.com/questions/11498508/ socket-emit-vs-socket-send для примеров.   -  person wenzul    schedule 08.10.2015
comment
Это довольно сложная проблема для объяснения, но я постараюсь отредактировать свой вопрос, чтобы уточнить детали. Спасибо за ваш отзыв!   -  person Dennis Decoene    schedule 08.10.2015
comment
Редактировал вопрос.   -  person Dennis Decoene    schedule 08.10.2015


Ответы (1)


Я собираюсь описать, как решить эту проблему, используя бета-версию Flask-SocketIO 1.0b1. Вы также можете сделать это с выпуском 0.6, но это немного сложнее, выпуск 1.0 упрощает работу с отдельными клиентами.

Каждому клиенту сокетного соединения назначается идентификатор сеанса, который однозначно его идентифицирует, так называемый sid. В обработчике функции сокета вы можете получить к нему доступ как request.sid. Кроме того, при подключении каждому клиенту назначается отдельная комната, названная по идентификатору сеанса.

Я предполагаю, что метаданные, которые вы получаете с обратным вызовом, позволяют идентифицировать пользователя. Вам нужно получить sid этого пользователя. Получив его, вы можете отправить уведомление в соответствующую комнату.

Пример (с некоторым размахиванием руки относительно того, как вы прикрепляете sid к адресу):

@app.route('/callback/<address>')
def callback(address):
    sid = get_sid_from_address(address)
    socketio.send('payment seen on blockchain', room=sid)

@socketio.on('address')
def socketlisten(address):
    associate_address_with_sid(address, request.sid)
person Miguel    schedule 08.10.2015
comment
Как и обещал, я попробовал это решение. Я ДУМАЮ, это сработает. Единственная проблема в том, что я запускаю приложение flask с mod_wsgi на apache. Я не хочу использовать socketio.run (app) с обратным прокси-сервером, потому что ненавижу запускаемые вручную процессы на производственном сервере. Так что я пока застрял на развертывании на нашем тестовом сервере. Поскольку другие сайты работают на этом сервере как виртуальные хосты apache, я также не могу просто переключиться на другое программное обеспечение веб-сервера. Так что, может быть, пришло время для выделенного сервера этого приложения ... - person Dennis Decoene; 20.10.2015
comment
@DennisDecoene, если вы используете Apache / mod_wsgi, у вас проблемы посерьезнее, чем socketio.run(). Насколько я понимаю, mod_wsgi плохо сочетается с фреймворками сопрограмм, я думаю, вы не сможете использовать eventlet или gevent, если развернете таким образом. Мне также неясно, какая поддержка mod_wsgi для WebSocket, я считаю, что он ее не поддерживает. - person Miguel; 20.10.2015
comment
Что ж, сейчас я тестирую автономный socket.run (), и я обновился до 1.0b4 на сервере и до 0.9.16 на клиенте, но я сдаюсь, потому что теперь получаю «Uncaught TypeError: Cannot read property» onClose 'of null' на клиенте. это клиентское соединение: var socket = io.connect ('http: //' + document.domain + ':' + location.port, {resource: 'socket.io'}); - person Dennis Decoene; 20.10.2015
comment
Вам нужно использовать 1.3.x на клиенте. См. Ссылку документация. - person Miguel; 21.10.2015
comment
О, конечно, раз уж я оставил всю штуку с wsgi, 0.9.16 мне больше не нужно !!! [берет пистолет, целится в мозг, стреляет: D] - person Dennis Decoene; 21.10.2015