Flask WebSockets

Salman Mehmood 15 febrero 2024
Flask WebSockets

Con esta explicación aprenderemos qué es un WebSocket y cómo funciona entre cliente y servidor. También aprenderemos cómo hacer una aplicación de chat en tiempo real con la ayuda del módulo Flask_socketio en Flask.

Cree una aplicación en tiempo real con la ayuda del WebSocket flask_socketio en Flask

Un WebSocket es una forma de abrir sockets entre un cliente y un servidor. Usando WebSockets, podemos enviar mensajes en tiempo real.

No es el típico modelo de solicitud-respuesta de la web; es como si siempre existiera una conexión abierta, y el servidor y el cliente pueden comunicarse entre sí constantemente.

Ahora construyamos la aplicación de chat; el primer lado que manejaremos es el lado del servidor. Hay dos lados: el primero es del lado del servidor, que se manejará desde Flask y el segundo es del lado del cliente, que se manejará desde JavaScript.

Una extensión flask_socketio permite que el cliente se conecte con el servidor, por lo que necesitaremos instalar el módulo flask_socketio usando el siguiente comando.

pip install Flask-SocketIO

Instalará flask_socketio junto con las dependencias que necesite. flask_socketio es muy similar a una aplicación de Flask típica, y los patrones son los mismos, pero algunas de las cosas que usamos son ligeramente diferentes.

Importaremos algunas clases y la función send para construir esta aplicación. Luego, crearemos una instancia de la aplicación y, dado que todos los mensajes están encriptados, necesitamos la clave secreta; definiremos la clave secreta como un valor config.

Ahora crearemos un objeto para la clase SocketIO() y lo instanciaremos pasando la aplicación, y el segundo argumento es permitir todos los dominios.

app.config["SECRET_KEY"] = "ffff111jjj52"
socketio = SocketIO(app, cors_allowed_origins="*")

Ahora definiremos una ruta que escuchará un evento particular que especifiquemos dentro de la ruta, y luego crearemos una función que será llamada en cualquier momento cuando enviemos el mensaje con el nombre de función Text_MSG().

Esta función toma un parámetro llamado msg, y lo imprimiremos para asegurarnos de que todo funciona en la consola.

Tomaremos el mensaje que provenga de cualquier persona y lo enviaremos a todos los que estén conectados al servidor en ese momento. Usaremos la función send(), que tomará dos parámetros: uno será el msg que es un mensaje de texto, y el segundo es un broadcast que será igual a True.

Si pasamos False al broadcast o no pasamos este argumento, entonces se enviará el mensaje de forma predeterminada a quienquiera que haya recibido el mensaje en primer lugar.

Dado que estamos transmitiendo y vamos a enviar el mismo mensaje que recibimos de un cliente, lo enviaremos de regreso a todos los clientes, incluido el cliente de quien lo acabamos de recibir.

@socketio.on("message")
def Text_MSG(msg):
    print("text-message: " + msg)
    send(msg, broadcast=True)

En lugar de usar app.run(), usaremos socketio.run(app), con funcionalidad adicional para ejecutar la aplicación del Flask en un entorno en tiempo real.

if __name__ == "__main__":
    socketio.run(app)

Entremos al edificio en la parte delantera, que será una página HTML. Importaremos un par de scripts desde un CDN para la biblioteca socket.io del lado del cliente. También usaremos jQuery para manejar el evento de clic en el botón.

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.8/socket.io.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

En la etiqueta body, escribiremos el código JavaScript. Debido a que estamos usando jQuery, tendremos que usar el método ready(), y dentro de este $(document).ready(), necesitaremos conectarnos al servidor donde se ejecuta la aplicación del Flask.

Crearemos un objeto llamado socket y lo instanciaremos usando connect() y pasaremos la URL para el servidor Flask. Una vez que hemos creado un objeto, debemos asegurarnos de que cuando nos conectemos al servidor, podamos enviarle un mensaje.

$(document).ready(function() {

    var socket = io.connect('http://127.0.0.1:5000');

    socket.on('connect', function() {
        socket.send('User has connected!');
    });

});

Significa que estamos escuchando un evento en particular, y el evento de conexión ocurre cada vez que nos conectamos por primera vez al servidor, y una vez que eso sucede, llama a esta función de devolución de llamada socket.on(). Esta función de devolución de llamada se enviará al servidor que el usuario ha conectado, y el servidor la recogerá para leerla y enviarla de vuelta a todos.

Agreguemos el código para duplicar cualquier mensaje enviado al servidor para escuchar otro evento en lugar de connect. La función de devolución de llamada de mensaje agregará los mensajes a nuestra lista de mensajes, y también fijaremos un elemento de la lista con el texto del mensaje.

socket.on('message', function(msg) {
    $("#messages").append('<li>'+msg+'</li>');
    console.log('Received message');
});

Lo último que haremos será permitir enviar un mensaje usando el botón. Así que colocaremos un evento de clic en el botón de envío y adjuntaremos la identificación de myMessage con la identificación de la etiqueta input.

Una vez que lo enviemos, borraremos nuestro mensaje para dejar espacio para un nuevo mensaje utilizando el método val('').

$('#sendbutton').on('click', function() {
    socket.send($('#myMessage').val());
    $('#myMessage').val('');
});

Ahora lo guardaremos y ejecutaremos el servidor Flask, y luego abriremos un archivo index.html en dos ventanas. Cuando ponemos texto dentro del campo de entrada y presionamos el botón send, recibiremos mensajes simultáneamente en otra ventana.

Flask WebSockets de salida

Nota: Si obtiene un error, ejecute los siguientes comandos dentro de la terminal.

pip install --upgrade python-socketio==4.6.0

pip install --upgrade python-engineio==3.13.2

pip install --upgrade Flask-SocketIO==4.3.1

Código Python completo:

from flask import Flask
from flask_socketio import SocketIO, send

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


@socketio.on("message")
def Text_MSG(msg):
    print("text-message: " + msg)
    send(msg, broadcast=True)


if __name__ == "__main__":
    socketio.run(app)

Código HTML completo:

<html>
<head>
<title>Chat Room</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.8/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>
<ul id="messages"></ul>
<input type="text" id="myMessage">
<button id="sendbutton">Send</button>
</body>
</html>
Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn