Search code examples
javascriptsocketssocket.ioflask-socketio

Is it possible to have multiple socket-io connections from a single client without loosing previous socket


I've been learning flask-socketio. The aim is to make a p2p-like (should not be correctly saying) chat app using socket-io which works in a LAN. All the users have static IP address which everyone knows. There are 4 devices in LAN. Each going to install the flask-app in their own system. This is the app.py and chat.html(client in JS)

This is the app.py

from flask import Flask,render_template,request,url_for,redirect
from flask_socketio import SocketIO,join_room

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

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

@app.route('/chat')
def chat():
    username = request.args.get('username')
    room    = request.args.get('room')

    if username and room:
        return render_template('chat.html',username=username,room=room)
    else:
        return redirect(url_for('home'))
        
@socketio.on('join_room')
def joinchannel(data):
    app.logger.info("{} is ONLINE NOW!".format(data['username']))
    join_room(data['room'])
    socketio.emit('join_room_announce',data)


if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0', port=5000,debug=True)

and the templates/chat.html

    <!DOCTYPE html>
<html>
<head>
    <title>START CHAT</title>
</head>
<body>

<h1>lets start the chat room {{ room }}</h1>
<div id="messages"></div>

<form>
    
    <input type="text" placeholder="enter message">
    <button type="submit">send</button>
</form> 
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
<script>
    const socket = io.connect("http://192.168.1.2:5000");
    socket.on('connect',function() {
        socket.emit('join_room',{
        username: "{{ username }}",
        room: "{{ room }}"
    })
});
    socket.on('join_room_announce', function (data) {
        alert(data.username);
    })
</script>
</html>

This is straight. Alice is running app.py in her system and trying to connect to Bob (192.168.1.2:5000). As Bob is runnning app.py in his system and inside LAN, Alice got connected. Bob as able to see "Alice" as a popup in his browser after Alice joined same room as Bob.

This is good. But what if Alice also want to connect with Frank (192.168.1.3:5000)? How can Alice modify her socketio connection in client side, server side to make it possible. I have tried adding another io.connect in chat.html. Therefore 2 io.connect function and only the first io.connect() is working.

If the straight answer is " this is not possible with socketio", is there some tweak to make it possible? Eventually Alice could connect to Bob, Frank or many and other members can also have same. Basically, one person should be able to connect with more than one person.

This may be possible with WebRTC-like protocols. But, this is not we want here. I hope there is some tweak to make this possible with socket-io. Thanks for reading!


Solution

  • yes, you can. you just have to put them in different variables.

    const socketConnectionOne = io.connect("http://192.168.1.2:5000");
    
    socketConnectionOne.on('connect',function() {
            socket.emit('join_room',{
            username: "{{ username }}",
            room: "{{ room }}"
        })
    });
    
    socketConnectionOne.on('join_room_announce', function (data) {
            alert(data.username);
        })
    
    const socketConnectionTwo = io.connect("http://192.168.1.2:5000");
    
    socketConnectionTwo.on('connect',function() {
            socket.emit('join_room',{
            username: "{{ username }}",
            room: "{{ room }}"
        })
    });
    
    socketConnectionTwo.on('join_room_announce', function (data) {
            alert(data.username);
        })