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

Time:07-28

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.

CodePudding user response:

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.

  • Related