How can my Flask application push Websocket Messages to an asynchronous HTML page?

I’m having a few issues with a Flask application using socketIO.

I have an external device on IP 10.0.0.144 sending websocket messages to my application on 10.0.0.218:8089. I can see the incoming websocket messages in the PyCharm console.

10.0.0.144 - - [31/Jul/2024 11:21:43] code 400, message Bad request syntax ('{"ts":1722439304,"dio":{"dio1":{"in":true},"dio2":{"in":true},"dio3":{"label":"Link","in":true},"dio4":{"in":true}},"ain":{"ain1":{"voltage":12},"ain2":{"voltage":2},"ain3":{"voltage":10},"ain4":{"voltage":0}}}') 

10.0.0.144 - - [31/Jul/2024 11:21:43] "{"ts":1722439304,"dio":{"dio1":{"in":true},"dio2":{"in":true},"dio3":{"label":"Link","in":true},"dio4":{"in":true}},"ain":{"ain1":{"voltage":12},"ain2":{"voltage":2},"ain3":{"voltage":10},"ain4":{"voltage":0}}}" HTTPStatus.BAD_REQUEST

Additionally I’m trying to push these messages to an asynchronous HTML page, but the messages aren’t being pushed across from what I can see.

Flask code:

I wanted this to process the incoming messages and then push them to an asynchronous HTML page. The messages are being processed, and I have them stored in a list object. I’m really only concerned with messages originating from 10.0.0.144.

I’m honestly not even sure if this is the best approach from a project standpoint, but I’ve never done anything this advanced before.


from flask_socketio import SocketIO, emit
from flask import Flask, render_template, url_for, copy_current_request_context
from random import random
from time import sleep
from threading import Thread, Event

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
app.config['DEBUG'] = True

#turn the flask app into a socketio app
socketio = SocketIO(app, async_mode=None, logger=True, engineio_logger=True)

thread = Thread()
thread_stop_event = Event()

messages = []

def get_values():
    while True:
        message = socketio.on(1024)
        while not thread_stop_event.is_set():
            messages.append(message)
            # Send the message to all connected clients
            socketio.emit('new_message', {'message': message})
            print(message)
            socketio.sleep(2)



@app.route('/')
def index():
    #only by sending this page first will the client be connected to the socketio instance
    return render_template('index.html')

@socketio.on('connect', namespace='/test')
def test_connect():
    # need visibility of the global thread object
    global thread
    print('Client connected')

    #Start the function to emit msgs thread only if the thread has not been started before.
    if not thread.is_alive():
        print("Starting Thread")
        thread = socketio.start_background_task(get_values)

@socketio.on('disconnect', namespace='/test')
def test_disconnect():
    print('Client disconnected')


# Start the Flask app with SocketIO
socketio.run(app, host='10.0.0.218', port=8089, allow_unsafe_werkzeug=True)

JS code:

$(document).ready(function(){
    //connect to the socket server.
    var socket = io.connect('http://10.0.0.218' + document.domain + ':' + location.port + '/test')
    var messages_received = [];

    //receive details from server
    socket.on('new_message', function(msg) {
        console.log("Received msg" + msg.number);
        //maintain a list of ten msgs
        if (messages_received.length >= 10){
            messages_received.shift()
        }
        messages_received.push(msg.number);
        messages_string = '';
        for (var i = 0; i < messages_received.length; i++){
            messages_string = messages_string + '<p>' + messages_received[i].toString() + '</p>';
        }
        $('#log').html(messages_string);
    });

});

Here’s a sample of the output console:

`* Running on http://10.0.0.218:8089
Press CTRL+C to quit

* Restarting with stat
  Server initialized for threading.
  Werkzeug appears to be used in a production deployment. Consider switching to a production web server instead.

* Debugger is active!

* Debugger PIN: 123-630-169
  RMoYImBp0_FvWs_lAAAA: Sending packet OPEN data {'sid': 'RMoYImBp0_FvWs_lAAAA', 'upgrades': ['websocket'], 'pingTimeout': 20000, 'pingInterval': 25000}
  10.0.0.218 - - [31/Jul/2024 11:54:54] "GET /socket.io/?EIO=4&transport=polling&t=P49W5nO HTTP/1.1" 200 -
  RMoYImBp0_FvWs_lAAAA: Received packet MESSAGE data 0/test,
  RMoYImBp0_FvWs_lAAAA: Received request to upgrade to websocket
  emitting event "new_message" to all [/]
  RMoYImBp0_FvWs_lAAAA: Sending packet MESSAGE data 0/test,{"sid":"Fzb-QYWF3SFFBr4EAAAB"}
  10.0.0.218 - - [31/Jul/2024 11:54:54] "POST /socket.io/?EIO=4&transport=polling&t=P49W64r&sid=RMoYImBp0_FvWs_lAAAA HTTP/1.1" 200 -
  10.0.0.218 - - [31/Jul/2024 11:54:54] "GET /socket.io/?EIO=4&transport=polling&t=P49W64s&sid=RMoYImBp0_FvWs_lAAAA HTTP/1.1" 200 -
  RMoYImBp0_FvWs_lAAAA: Upgrade to websocket successful
  Client connected
  Starting Thread
  emitting event "new_message" to all [/]
  emitting event "new_message" to all [/]
  10.0.0.144 - - [31/Jul/2024 11:54:59] code 400, message Bad request syntax ('{"ts":1722441301,"dio":{"dio1":{"in":true},"dio2":{"in":true},"dio3":{"label":"Link","in":true},"dio4":{"in":true}},"ain":{"ain1":{"voltage":12},"ain2":{"voltage":2},"ain3":{"voltage":10},"ain4":{"voltage":0}}}')
  10.0.0.144 - - [31/Jul/2024 11:54:59] "{"ts":1722441301,"dio":{"dio1":{"in":true},"dio2":{"in":true},"dio3":{"label":"Link","in":true},"dio4":{"in":true}},"ain":{"ain1":{"voltage":12},"ain2":{"voltage":2},"ain3":{"voltage":10},"ain4":{"voltage":0}}}" HTTPStatus.BAD_REQUEST -
  emitting event "new_message" to all [/]
  emitting event "new_message" to all [/]
  emitting event "new_message" to all [/]
  10.0.0.218 - - [31/Jul/2024 11:55:05] "GET /socket.io/?EIO=4&transport=websocket&sid=RMoYImBp0_FvWs_lAAAA HTTP/1.1" 200 -
  10.0.0.218 - - [31/Jul/2024 11:55:05] "GET / HTTP/1.1" 200 -
  Client disconnected
  10.0.0.218 - - [31/Jul/2024 11:55:05] "GET /static/application.js HTTP/1.1" 304 -`

HTML page:

<!DOCTYPE html>
<html>
<head>
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.1/socket.io.min.js"></script>
    <script src="static/application.js"></script>

    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="container">
  <div class="jumbotron">
    <h2>Asynchronous Flask Communication</h2>
    <p>Websocket Messages from field devices.</p>
  </div>
</div>

</div>

<div class="container" id="content">
    <div class="row">
        <p>Asynchronous page updates will appear here:</p>
        <h3>messages:</h3>
        <div id="log">
        </div> <!-- /#log -->
    </div>
</div>


</body>
</html>