Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

659
Views
Flask socketio no escucha eventos

Estoy creando una aplicación de matraz utilizando el socketio del matraz. Lo estoy ejecutando localmente en Ubuntu 20.04 con gunicorn y eventlet en localhost:8000.

Mi código de prueba del lado del servidor se ve así:

 $(document).ready(function() { // const socketGame = io(window.location.hostname + "/coin") var socket = io.connect('http://127.0.0.1:8000'); socket.on('connect', function() { console.log("ok"); socket.send('User has connected!'); }); socket.on('message', function(msg) { console.log('Received message'); }); });

y en mi servidor tengo el siguiente oyente:

 import re from flask import render_template, request, redirect, url_for, jsonify, current_app from flask_mail import Mail, Message from flask_socketio import emit, join_room, leave_room, rooms from flask_login import LoginManager, UserMixin, login_user, login_required, current_user, logout_user from werkzeug.security import generate_password_hash, check_password_hash from .. import socketio from . import games_blueprint from app.models import * from app.utilities import sanitizeHtml #socketio chat server #need to create event for admin broadcasting messages @socketio.on('message', namespace='/') def handleMessage(msg): print('Message: ' + msg) send(msg, broadcast=True)

Simplemente debe imprimir el mensaje del cliente en la terminal y transmitir un mensaje. Pero, según los registros de gunicorn, parece que el servidor recibe el evento del cliente y no se lo pasa al oyente:

 (vegazbetenv) jveiga@LAPTOP-C6PJKMM6:~/vegazbet$ gunicorn --worker-class eventlet -w 1 wsgi:application [2021-11-24 21:00:59 -0300] [134633] [INFO] Starting gunicorn 20.1.0 [2021-11-24 21:00:59 -0300] [134633] [INFO] Listening at: http://127.0.0.1:8000 (134633) [2021-11-24 21:00:59 -0300] [134633] [INFO] Using worker: eventlet [2021-11-24 21:00:59 -0300] [134635] [INFO] Booting worker with pid: 134635 Server initialized for eventlet. Server initialized for eventlet. Server initialized for eventlet. HYYx0QNgrNr7YodDAAAA: Sending packet OPEN data {'sid': 'HYYx0QNgrNr7YodDAAAA', 'upgrades': ['websocket'], 'pingTimeout': 20000, 'pingInterval': 25000} HYYx0QNgrNr7YodDAAAA: Received packet MESSAGE data 0 HYYx0QNgrNr7YodDAAAA: Sending packet MESSAGE data 0{"sid":"q1NjSbTlPRYmT_TYAAAB"} HYYx0QNgrNr7YodDAAAA: Received request to upgrade to websocket HYYx0QNgrNr7YodDAAAA: Received packet MESSAGE data 2["message","User has connected!"] received event "message" from q1NjSbTlPRYmT_TYAAAB [/] HYYx0QNgrNr7YodDAAAA: Upgrade to websocket successful HYYx0QNgrNr7YodDAAAA: Sending packet PING data None HYYx0QNgrNr7YodDAAAA: Received packet PONG data

Como se puede ver en los registros, la conexión websocket se actualizó con éxito y el servidor socket-io recibe el mensaje del cliente, simplemente no lo pasa a la función que se suponía que escucharía el evento.

Solo para aclarar, estoy ejecutando el matraz usando el patrón de la fábrica de aplicaciones, el código del oyente está dentro de un archivo de vista de blueprint.py, sigue mi código para la fábrica de aplicaciones y blueprint:

 app/__init__.py import os from flask import Flask, jsonify, render_template, request, redirect, url_for from flask_login import LoginManager, UserMixin, login_user, login_required, current_user, logout_user from flask_mail import Mail from flask_socketio import SocketIO from flask_mongoengine import MongoEngine from flask_wtf.csrf import CSRFProtect from celery import Celery from config import Config from app.models import * from config import * ### Flask extension objects instantiation ### mail = Mail() csrf = CSRFProtect() login_manager = LoginManager() # socketio = SocketIO(engineio_logger=True, logger=True, message_queue=os.getenv('CELERY_BROKER_URL'), cors_allowed_origins="*") socketio = SocketIO(engineio_logger=True, logger=True, cors_allowed_origins="*") ### Celery instantiation ### celery = Celery(__name__, broker=Config.CELERY_BROKER_URL, result_backend=Config.RESULT_BACKEND) ### Application Factory ### def create_app(): app = Flask(__name__) # Configure the flask app instance CONFIG_TYPE = os.getenv('CONFIG_TYPE', default='config.DevelopmentConfig') app.config.from_object(CONFIG_TYPE) #Configure celery celery.conf.update(app.config) # Initialize flask extension objects initialize_extensions(app) # Register blueprints register_blueprints(app) #setup db integration configure_db(app) # Configure logging configure_logging(app) # Register error handlers register_error_handlers(app) #setup db for flask-login @login_manager.user_loader def load_user(user_id): user = User.objects(id=user_id)[0] return user return app ### Helper Functions ### def register_blueprints(app): from app.auth import auth_blueprint from app.main import main_blueprint from app.games import games_blueprint from app.admin import admin_blueprint app.register_blueprint(auth_blueprint, url_prefix='/users') app.register_blueprint(main_blueprint) app.register_blueprint(games_blueprint, url_prefix='/games') app.register_blueprint(admin_blueprint, url_prefix='/admin') def initialize_extensions(app): mail.init_app(app) login_manager.init_app(app) csrf.init_app(app) socketio.init_app(app) def register_error_handlers(app): # 400 - Bad Request @app.errorhandler(400) def bad_request(e): return render_template('400.html'), 400 # 401 - Unauthorized @app.errorhandler(401) def bad_request(e): return render_template('401.html'), 401 # 403 - Forbidden @app.errorhandler(403) def forbidden(e): return render_template('403.html'), 403 # 404 - Page Not Found @app.errorhandler(404) def page_not_found(e): return render_template('404.html'), 404 # 405 - Method Not Allowed @app.errorhandler(405) def method_not_allowed(e): return render_template('405.html'), 405 # 500 - Internal Server Error @app.errorhandler(500) def server_error(e): return render_template('500.html'), 500 def configure_logging(app): import logging from flask.logging import default_handler from logging.handlers import RotatingFileHandler # Deactivate the default flask logger so that log messages don't get duplicated app.logger.removeHandler(default_handler) # Create a file handler object file_handler = RotatingFileHandler('flaskapp.log', maxBytes=16384, backupCount=20) # Set the logging level of the file handler object so that it logs INFO and up file_handler.setLevel(logging.INFO) # Create a file formatter object file_formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(filename)s: %(lineno)d]') # Apply the file formatter object to the file handler object file_handler.setFormatter(file_formatter) # Add file handler object to the logger app.logger.addHandler(file_handler) def configure_db(app): db = MongoEngine(app)
 app/games/__init__.py #This bluepint will deal with all site functionality from flask import Blueprint games_blueprint = Blueprint('games', __name__, template_folder='templates') from . import views

¿Alguna idea de por qué sucede esto y cómo solucionarlo?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Su cliente está buscando socket.on('message', incoming_message_as_a_string) pero su servidor está enviando socket.send('just the string without an event')

Tratar:

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

pero me acostumbraría a usar emit siempre, tanto en el cliente como en el servidor:

 socket.on('connect', function() { console.log("ok"); socket.emit('message', 'User has connected!'); });

La razón es que emit puede enviar tanto objetos como cadenas, mientras que send solo puede enviar cadenas.


Actualizar:

Mirando de nuevo tu pregunta, no creo que tus dos lados coincidan. Cuando se envía un mensaje de socket, el primer parámetro es el "nombre del evento", básicamente un desencadenante que le da al otro lado algo que observar (para que los oyentes del socket puedan diferenciar entre diferentes tipos de mensajes).

El servidor solo escucha un evento de message y luego envía su propio message , lo que significa que el lado del cliente tiene que enviar algo primero. Por lo general, ese es un mensaje de "conexión", y envía uno de esos cuando el cliente se conecta, pero el lado del servidor no está escuchando ese evento. Solo escucha un evento de "mensaje", y el lado del cliente solo envía un evento de message después de recibir un evento de mensaje del servidor.

En el lado del servidor, intente cambiar esto:

 @socketio.on('message', namespace='/') def handleMessage(msg): print('Message: ' + msg) send(msg, broadcast=True)

a esto:

 @socketio.on('connect') def handleConnect(): print('Someone connected') send('message', 'A user has joined', broadcast=True) @socketio.on('message') def handleMessage(msg): print('Message: ' + msg) send(msg, broadcast=True)

PD: eliminé las cosas del espacio de nombres porque hice que las cosas funcionaran sin él y no estoy seguro de cómo podría afectar los resultados. Puede volver a agregarlo una vez que haya avanzado un poco más.

over 4 years ago · Santiago Trujillo Report

0

No estoy muy seguro de los detalles finos aquí, pero la siguiente alteración hizo que el servidor funcionara.

En la función original de la fábrica de aplicaciones, llamaba a socketio.init_app(app) antes de registrar los planos. Acabo de moverlo para que sea la última operación en la fábrica de aplicaciones:

 def create_app(): app = Flask(__name__) # Configure the flask app instance CONFIG_TYPE = os.getenv('CONFIG_TYPE', default='config.DevelopmentConfig') app.config.from_object(CONFIG_TYPE) #Configure celery celery.conf.update(app.config) # Register blueprints register_blueprints(app) #setup db integration configure_db(app) # Configure logging configure_logging(app) # Register error handlers register_error_handlers(app) ########################################## # HERE # Initialize flask extension objects initialize_extensions(app) ########################################## #setup db for flask-login @login_manager.user_loader def load_user(user_id): user = User.objects(id=user_id)[0] return user return app

Supongo que el orden de operación de alguna manera impide que socketio registre los controladores de eventos. Agradecería que alguien con más experiencia con matraz-socketio pudiera profundizar en el tema.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!