Невозможно передать событие кнопки Flask SocketIO во внешнюю программу Python - PullRequest
0 голосов
/ 29 сентября 2018

Мне нужно разделить мое веб-приложение на Python Flask и запустить код, общающийся через socketio.Я могу получать сообщения из внешней программы Python в Интернет, но я не могу получать события из Интернета, обнаруженные программой Python.По сути, мне бы хотелось, чтобы пользователь нажимал кнопку на веб-странице, чтобы внешний код Python печатался на терминале сообщения Hello World.В консоли для этого html я определенно вижу «Нажатие кнопки».

<html>
<head>
<title>Listener</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.8/socket.io.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function() {
    var socket = io.connect();

    $('#mybutton').on('click', function() {
        socket.emit('my event', 'yodle');
        console.log('Button pressed');
    });
});
</script>
<button id="mybutton">Push Me!</button>
</body>
</html>

Это мой основной код веб-сервера Flask, который работает:

from flask import Flask, render_template
from flask_socketio import SocketIO

app = Flask(__name__)
app.config['SECRET_KEY'] = 'froggy'
app.debug = True
socketio = SocketIO(app, message_queue='redis://')

@app.route("/")
def index():
  return render_template("index.html")

if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0')

Это мойотдельная запущенная программа, которая ничего не печатает на терминал при нажатии кнопки:

from flask_socketio import SocketIO

socketio = SocketIO(message_queue='redis://', host='0.0.0.0')

def my_function_handler(data):
    print("Hello World")

if __name__ == '__main__':
    while True:
        socketio.on_event('my event', my_function_handler)

Может кто-нибудь указать мне, где я иду не так?Большое спасибо заранее!

Ответы [ 2 ]

0 голосов
/ 30 сентября 2018

Очевидно, что это поведение не поддерживается в socketIO в соответствии с ответом Мигеля, поэтому я публикую свое конкретное решение проблемы, если кому-то будет интересно.Я проводил много времени в поисках в Google, переполнении стека и вообще падении в кроличьи норы.Я закончил тем, что, поскольку я уже использовал redis, я просто использовал его для передачи сообщений между процессами.У этого подхода есть масса недостатков, но он прекрасно соответствует моим потребностям, так что вот что я сделал.Для index.html:

<html>
<head>
<title>Listener</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.8/socket.io.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function() {
    var socket = io.connect();

    $('#mybutton').on('click', function() {
        socket.emit('button event');
    });
});
</script>
<button id="mybutton">Push Me!</button>
</body>
</html> 

Код сервера:

from flask import Flask, render_template
from flask_socketio import SocketIO
import redis

app = Flask(__name__)
app.config['SECRET_KEY'] = 'froggy'
app.debug = True
socketio = SocketIO(app, message_queue='redis://')

r = redis.Redis("localhost")
r.set('button', 'not pressed')

@app.route("/")
def index():
  return render_template("index.html")

@socketio.on('button event')
def handleMessage():
    r.set('button', 'pressed')

if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0')

Отдельный рабочий процесс:

import redis

r = redis.Redis("localhost")

if __name__ == '__main__':
    while True:
        if r.get('button') == 'pressed':
            print("Button pressed!")
            r.set('button', 'not pressed')
0 голосов
/ 30 сентября 2018

Вы пытаетесь сделать что-то, что не поддерживается.Внешние процессы могут только излучать, они не являются получателями.Если вам нужно отправлять и получать данные во внешнем процессе, я рекомендую полностью переместить сервер Socket.IO в этот процесс.

...