Unable to handle click events for individual buttons

Question:

What I want to do: I have two buttons in my html client. I want to handle button click events on the server side using two different and separate event-handler functions.

I will click any button, and upon clicking, the client will send a text message to the server and the server will print it on the console using python’s print()-function.

What problem I am facing: The server is printing the first message up on the first connection.

However, subsequent button clicks are not achieving the desired result. I am clicking the buttons, the server is not printing the texts sent by the client.

How can I achieve what I am aiming for? What am I doing incorrectly?


client_sends_control_content.py

# client sends,
# server receives.

from flask import Flask, render_template
from flask_socketio import SocketIO, emit
import logging

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


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


@socketio.on('my_event1', namespace='/test')
def handle_my_event1(arg1):
    try:
        print('received_1 : ' + str(arg1['data1']))
    except Exception as ex:
        logging.exception("")
        print(ex)


@socketio.on('my_event2', namespace='/test')
def handle_my_event2(arg2):
    try:
        print('received_2 : ' + str(arg2['data2']))
    except Exception as ex:
        logging.exception("")
        print(ex)


@socketio.on('my_event3', namespace='/test')
def handle_my_event3(arg3):
    try:
        print('received_3 : ' + str(arg3['data3']))
    except Exception as ex:
        logging.exception("")
        print(ex)


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

client_sends_control_content.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>click demo</title>
    <script src="https://code.jquery.com/jquery-3.5.0.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
    <script>
        let namespace = '/test';
        let socket = io(namespace);

        //connect to the server on page load
        $(function(){
            socket.on('connect', function(){
                socket.emit('my_event1', {'data1' : 'Hello World!'});
                //alert("connected!")
            });

            $('#button2').click(function(){
                socket.on('connect', function(){
                    let text2 = "2 2 2 2 2 2"
                    socket.emit('my_event2', {'data2' : text2});
                });
                //alert('btn2 clicked!')
            });

            $('#button3').click(function(){
                socket.on('connect', function(){
                    let text3 = "3 3 3 3 3 3"
                    socket.emit('my_event3', {'data3' : text3});
                });
                //alert('btn3 clicked!')
            });
        });
    </script>
</head>
<body>
    <input id="button2" type="button" value="Button 2">
    <input id="button3" type="button" value="Button 3">
</body>
</html>
Asked By: user366312

||

Answers:

socket.on('connect', registers a callback for when the WebSocket connects from the client to the server. Registering a function to handle a click event from jQuery means that function will only be called when you click the element it is attached to. Your code registers a new callback for connect events when the button is pressed. But because the original connect event is handled already by the first callback, registering further callbacks results in nothing happening. You want to change the on('connect1' handler registrations within the button click handlers to just emit the message to the server.

            $('#button2').click(function(){
                let text2 = "2 2 2 2 2 2";
                socket.emit('my_event2', {'data2' : text2});
                //alert('btn2 clicked!')
            });
Answered By: ricardkelly