Skip to content
Advertisement

How to separate the socketio connection by the path of the URL in my flask chat app

I am trying to build a chat app using Flask-socketio, where clubs can have their members talk to each other. The app differentiates the chats of different clubs using arguments in the URL, as shown in the “/chat/<club_code>” route. However, the socketio connection is updating both chats with the messages of both clubs (club1 and club2). How do I make it so messages sent in “/chat/club1” can only be seen by people on that particular route, and messages sent in “/chat/club2” can only be seen by people on that particular route.

Frontend code:

<html>
<head>
<title>Chat Room</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.0/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('http://127.0.0.1:5000');

    socket.on('connect', function() {
        socket.send('User has connected!');
    });

    socket.on('message', function(msg) {
        $("#messages").append('<li>'+msg+'</li>');
        console.log('Received message');
    });

    $('#sendbutton').on('click', function() {
        socket.send($('#myMessage').val());
        $('#myMessage').val('');
    });

});
</script>
<b>this is the chat for {{club_code}}</b>
<ul id="messages"></ul>
<input type="text" id="myMessage">
<button id="sendbutton">Send</button>
</body>
</html>

Backend code:

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

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

club_list = ['Club1', 'Club2']

@socketio.on('message')
def handleMessage(msg):
    print('Message: ' + msg)
    send(msg, broadcast=True)

@app.route('/chat/<club_code>')
def chat(club_code):
    return render_template('chat.html',club_code=club_code)

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

What is happening now.

Advertisement

Answer

You can store the club code in the session, then use rooms to only send the message to users in a certain club.

from flask import Flask, render_template, session
from flask_socketio import SocketIO, send, join_room

@socketio.on('message')
def handleMessage(msg):
    print('Message: ' + msg)
    send(msg, broadcast=True, to = session['club_code'])
    
@socketio.on('connect')
def connect():
    join_room(session['club_code'])

@app.route('/chat/<club_code>')
def chat(club_code):
    session['club_code'] = club_code
    return render_template('chat.html',club_code=club_code)

When the user loads the page, the club_code session variable is set. When the connect event occurs, the user is joined into a room for their club_code. Then you can use the to parameter of the send method to send the message to the relevant club. See the socket.io and flask-socketio docs about rooms for more information.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement