웹 소켓(WebSocket)을 사용하기 위한 패키지입니다. 웹 소켓은 실시간 양방향 통신을 제공하는 프로토콜로, 서버와 클라이언트 간에 지속적인 연결을 통해 데이터를 실시간으로 주고받을 수 있게 해줍니다.
실시간 양방향 통신
웹 소켓을 사용하여 클라이언트와 서버 간에 양방향 실시간 통신을 구현할 수 있습니다. 이를 통해 서버가 클라이언트로 데이터를 보내고, 클라이언트도 서버로 데이터를 보낼 수 있습니다.
이벤트 기반 통신
클라이언트와 서버 간의 통신은 이벤트(Event)를 기반으로 이루어집니다. 서버나 클라이언트에서 이벤트를 발생시키고, 그에 대응하는 핸들러를 등록하여 해당 이벤트가 발생했을 때 특정 동작을 수행할 수 있습니다.
Socket.IO 프로토콜 사용
Flask-SocketIO는 Socket.IO 프로토콜을 기반으로 동작합니다. Socket.IO는 실시간 양방향 통신을 위한 다양한 기능과 안정성을 제공하는 프로토콜입니다.
간편한 통합
Flask 애플리케이션과의 통합이 간단하며, 기존의 Flask 애플리케이션에 손쉽게 웹 소켓 기능을 추가할 수 있습니다.
💡 본 글은 예제 코드를 이용하여 설명합니다.
flask/source/my_app/__init__.py을 살펴보면 flask_socketio의 SocketIO
객체를 생성하고 초기화합니다.
캐시를 초기화하고 싶다면 Cache 객체의 clear()를 호출하면 됩니다.
sock = SocketIO()
# 코드 생략
def create_app():
app.config.from_object(obj=config["development"])
with app.app_context():
# 코드 생략
sock.init_app(app=app)
return app
__init__.py에서 생성한 객체를 이용하여 flask/source/wsgi.py에서 애플리케이션을 구동합니다.
from my_app import create_app, sock
app = create_app()
if __name__ == "__main__":
sock.run(app=app, host="0.0.0.0", port=5000, allow_unsafe_werkzeug=True)
flask/source/my_app/views/dashboard.py를 살펴봅니다.
웹 클라이언트에서 웹 소켓이 연결을 시도하게 되면 connect
라는 메시지로 처리할 수 있습니다.
본 예제에서는 웹 소켓이 연결되었을 때, 백그라운드로 background_thread라는 함수를 수행하는 예제입니다.
@sock.on(message="connect")
@login_required
@role_required(["ADMIN"])
def connect():
global thread
with thread_lock:
if thread is None:
thread = sock.start_background_task(background_thread)
백엔드는 준비가 되었으니 프론트엔드에서 웹 소켓을 사용해 줍니다.
별도의 웹 소켓을 구현하지 않고 웹 소켓을 사용하기 위해서는 라이브러리가 필요합니다.
flask/source/my_app/templates/base.html에서 웹 소켓을 사용할 수 있는 라이브러리를 불러옵니다.
<script src="https://cdn.socket.io/4.7.2/socket.io.min.js" integrity="sha384-mZLF4UVrpi/QTWPA7BjNPEnkIfRFn4ZEO3Qt/HFklTJBj/gBOV8G3HcKn4NfQblz" crossorigin="anonymous"></script>
이후, flask/source/my_app/templates/admin/dashboard.html에서 웹 소켓을 이용하여 서버에 접속합니다.
var socket = io.connect();
flask/source/my_app/views/dashboard.py를 살펴봅니다.
emit()
을 이용하여 updateResource라는 이벤트 이름으로 이벤트를 발생시킵니다.
이벤트를 발생할 때, 연결된 클라이언트에게 주는 데이터는 server_resource()의 반환 값으로 사용하였습니다.
def background_thread():
while True:
sock.emit("updateResource", server_resource())
다시 flask/source/my_app/templates/admin/dashboard.html로 돌아와 봅니다.
이벤트가 발생되면 on()
을 이용하여 이벤트를 수신할 수 있습니다.
socket.on("updateResource", function (msg) {
// 코드 생략
}
본 예제에서는 서버가 이벤트를 지속적으로 발생시키는 구조인데, 클라이언트에서 emit을 사용하고 서버에서 on을 통해 이벤트를 수신하는 구조도 가능합니다.