WebSocket

2023. 12. 11. 11:15Flask

http 통신은 기본적으로 단방향 통신이다

따라서 client에 서버는 요청을 보낼 수 없는데 이를 해결하기 위하여 사용하는 방법중 하나가 websocket이다

python에서 websocket은 socketio 라이브러리를 사용하여 구현 할 수 있다

 

run.py

from web_project.chatting.socket_test import socketio
socketio.run(app, port=5000)

 

extension.py

from flask_socketio import SocketIO
socketio = SocketIO()

 

__init__.py

socketio.init_app(app)

 

socket_test.py

from flask import Blueprint, render_template, request
from flask_socketio import emit, send
from .extension import socketio
web_socket = Blueprint("socket",__name__,url_prefix= '/socket')

users = {}

@web_socket.route('/chat', methods = ['GET','POST',])
def chatting():
    return render_template("chatting/chat.html")
    

@socketio.on("connect")
def handle_connect():
    print("Client connected!")

@socketio.on("user_join")
def handle_user_join(username = "default"):
    print(f"User {username} joined!")
    users[username] = request.sid

@socketio.on("new_message")
def handle_new_message(message):
    print(f"New message: {message}")
    username = None 
    for user in users:
        if users[user] == request.sid:
            username = user
    emit("chat", {"message": message, "username": username}, broadcast=True)

 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Flask-SocketIO Example</title>
    <script src="https://cdn.socket.io/4.6.0/socket.io.min.js" integrity="sha384-c79GN5VsunZvi+Q/WObgk2in0CbZsHnjEqvFxC5DxHn9lTfNce2WW6h2pH6u/kF+" crossorigin="anonymous"></script>
</head>
<body>
    <div id="landing">
        <input type="text" id="username" placeholder="Username">
        <button id="join-btn">JOIN</button>
    </div>

    <div id="chat" style="display:none;">

        <ul id="chat-messages">
        </ul>
        <input type="text" id="message" placeholder="Enter a Message">
        <button id="exit">EXIT</button>
    </div>
    <script type="text/javascript">
        const socket = io({autoConnect: false});

        document.getElementById("join-btn").addEventListener("click", function() {
            let username = document.getElementById("username").value;
            socket.connect();
            socket.on('connect', function() {
                console.log('connect');
                socket.emit('user_join', username);
            });
            
            document.getElementById("chat").style.display = "block";
            document.getElementById("landing").style.display = "none";
        })

        document.getElementById("message").addEventListener("keyup", function (event) {
            if (event.key == "Enter") {
                let message = document.getElementById("message").value;
                console.log(message)
                socket.emit("new_message", message);
                document.getElementById("message").value = "";
            }
        })

        socket.on("chat", function(data) {
            let ul = document.getElementById("chat-messages");
            let li = document.createElement("li");
            li.appendChild(document.createTextNode(data["username"] + ": " + data["message"]));
            ul.appendChild(li);
            ul.scrolltop = ul.scrollHeight;
        })

        document.getElementById("exit").addEventListener("click", function() {
            socket.disconnect();
            location.replace("{{ url_for('main.main_page') }}");
        })
    </script>
</body>
</html>

'Flask' 카테고리의 다른 글

CSRF  (0) 2023.12.11
Session login  (0) 2023.12.11
MongoDB  (0) 2023.12.11
Route  (0) 2023.12.11
render_template  (0) 2023.12.10