0

I'm working on a project where I have a Flask server, and I'm trying to use flask-socketio to send messages to the front-end react component. Apologies in advance for any lack of understanding. I have no prior experience in web development and am a novice.

Below is the relevant parts of the Flask server code:

import subprocess
import sqlite3
import time
import signal
import sys
from datetime import datetime
import socket
import threading
import json
from queue import Queue
import errno

from flask import Flask
from flask_socketio import SocketIO, emit, send 

NUM_CLIENTS = 0  # 需要连接的客户端数量
connected_clients = 0
clients = {}
client_queues = {}  # 用于存储每个客户端的消息队列
pv_buffer = []
grid_buffer = []
led1_buffer = []
led2_buffer = []
led3_buffer = []
led4_buffer = []

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, cors_allowed_origins="*")

@app.route('/')
def index():
    return "Flask server for handling client data and WebSocket communications"

def start_socketio_server():
    print("Starting Flask-SocketIO server...")
    socketio.run(app, debug=False, host='0.0.0.0', port=3003) 

if __name__ == '__main__':
    

    electricneed = 0
    electricsupply = 0
    stored = 0
    Max_store = 50
    basic = 0
    buy_rate = 0
    sell_rate = 0
    balance = 0
    former = 0
    old_day = None
    data = getdata()
    pre_tick = -1
    webfetch_process = subprocess.Popen(['python', 'webfetch.py'])

    signal.signal(signal.SIGINT, signal_handler)

    try:
        server_socket = start_server()

        client_accept_thread = threading.Thread(target=accept_clients, args=(server_socket,))
        client_accept_thread.start()

       
        
        socketio_thread = threading.Thread(target=start_socketio_server)
        socketio_thread.start()
        print("Flask-SocketIO server started successfully.")
        while True:
            while connected_clients < NUM_CLIENTS:
                print(f'Waiting for all clients to connect... ({connected_clients}/{NUM_CLIENTS})')
                time.sleep(1)

            print('All clients connected. Starting main logic.')

            while connected_clients >= NUM_CLIENTS:
                data = getdata()
                if data[1] != pre_tick:
                    buy = 0
                    sell = 0
                    day = data[0]
                    if day != old_day:
                        deferable = getdeferable()
                    old_day = day
                    if data:
                        data = list(data)
                        u1 = 0
                        u2 = 0
                        u3 = 0
                        u4 = 0
                        if former == 0:
                            former = data[4]
                        data[3] = data[3] * 5
                        if data[0] in range(25, 36):
                            data[3] += 5
                        data = deferable_calc(data, deferable)
                        electricsupply = data[2] * 0.05 * 5
                        electricneed = data[3]
                        buy_rate = data[4]
                        sell_rate = data[5]
                        result = balance_calc(data[1], electricsupply, electricneed, buy_rate, sell_rate, stored, former)
                        balance += result[0]
                        stored += result[1]
                        if electricneed / 5 <= 4:
                            u1 = u2 = u3 = 1
                            u4 = electricneed / 5 - 3
                        elif electricneed / 5 > 2:
                            u1 = u2 = 1
                            u3 = electricneed / 5 - 2
                        elif electricneed / 5 > 1:
                            u1 = 1
                            u2 = electricneed / 5 - 1
                        else:
                            u1 = electricneed / 5

                        state = result[2]
                        if result[1] == 0:
                            state = 1
                        power = abs(data[1])
                        #message = [day, data[1], data[2], state, power / 5, u1, u2, u3, u4]
                        message = {
                            'tick': data[1],
                            'pv_power': 0.046*data[2],
                            'state': state,
                            'charge_power': (result[1] / 5)
                        }
                        print("current tick:", data[1], "   PV power:", (0.046 * data[2]), "    state:", state, "   charge power:", (result[1] / 5), "    user power:", [u1, u2, u3, u4])
                        pre_tick = data[1]

                        update_info()

                        for client_id, client_queue in client_queues.items():
                            client_queue.put(message)

                        
                        try:
                            print("Emitting message:", message)
                            socketio.emit('message', message)
                            print("data sent from python server")
                        except Exception as e:
                            print(f"Error emitting message: {e}")

    except Exception as e:
        print(f"An error occurred: {e}")
    finally:
        webfetch_process.terminate()
        webfetch_process.wait()



And my react component:

import React, { useEffect, useState } from 'react';
import io from 'socket.io-client';

// URL for your socket server
const SOCKET_URL = 'http://localhost:3003';

const SocketComponent = () => {
  const [tick, setTick] = useState(null);

  useEffect(() => {
    // Connect to the socket server
    const socket = io(SOCKET_URL);

    socket.on('connect', () => {
      console.log('Connected to python Socket.IO server');
    });

    socket.on('disconnect', () => {
      console.log('Disconnected from python Socket.IO server');
    });

    // Listen for messages from the server
    socket.on('message', (message) => {
      console.log('Received message:', message);
      setTick(message.tick);
    });

    // Cleanup on unmount
    return () => {
      socket.disconnect();
    };
  }, []);

  return (
    <div>
      <h1>Current Tick Value</h1>
      <p>{tick !== null ? tick : 'Waiting for tick value...'}</p>
    </div>
  );
};

export default SocketComponent;

Currently, when running the Flask server with the TCP client logic disabled, the following is printed to terminal on the server side:

current tick: 4    PV power: 0.0     state: 1    charge power: 0.0     user power: [1, 1, 1, -0.2660664554520613]
Error: data lenghth must larger than 2
Emitting message: {'tick': 4, 'pv_power': 0.0, 'state': 1, 'charge_power': 0.0}
data sent from python server

Which I think indicates that the message has been successfully emitted.

However, on the frontend side, the react component will connect to the server - Connected to python Socket.IO server but will never receive any messages? According to my react component whenever a message is received it should log to console?

I really have no clue why the messages are not being received, and I'd greatly appreciate any help on the matter.

No visible errors occur- the main issue is that on the Flask server side it shows that messages are being emitted however nothing appears to be received by the frontend react component.

1
  • Do you have eventlet or gevent installed on your Python virtualenv? If you do, try uninstalling them. Commented Jun 13 at 22:38

0