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)
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.