I am experimenting with Flask-Sockets. Support for Blueprints was added in the past, something I really do need.
from flask import Flask, request, abort, redirect, url_for, render_template, make_response, Response, jsonify, session
import json
#Importing blueprints
from play import play, play_socket
app = Flask(__name__)
sockets = Sockets(app)
app.register_blueprint(play, url_prefix=r"/play")
sockets.register_blueprint(play_socket, url_prefix=r"/play")
@sockets.route('/echo')
def echo_socket(ws):
while not ws.closed:
message = ws.receive()
response = json.dumps({"Message":message,"Response":"Message received"})
ws.send(response)
So, connecting a websocket in JavaScript and setting the endpoint to 'echo' (i.e. var ws = new WebSocket("ws://HOST:PORT/"+"echo")
) works perfectly. I can send messages and they get bounced right back at me.
However, when I want to move this function to a blueprint (in the blueprint play_socket
, it doesn't work anymore. Assume I changed the endpoint to '/status_ping' in the javascript:
@play_socket.route('/status_ping')
def ping(ws):
while not ws.closed:
message = ws.receive()
response = json.dumps({"Message":message,"Response":"Message received"})
ws.send(response)
The websocket is connected successfully from the client-side and I can confirm this by inserting a simple print("HERE")
or whatever in the def ping(socket):
, but it's immediately closed afterwards, rendering it useless.
I found out that if I move the body of the while not ws.closed:
loop above the header (copy it), it 'works'. However, I can't use this as I need the socket to push data from the server to the clients. It seems to be going wrong when this while loop is executed. The socket is immediately closed for some reason. changing while not ws.closed:
to while True:
has no effect.
I tried to isolate the problem as much as I could, but please let me know if you need more info.
EDIT: Codesample for blueprint
from flask import Flask, request, abort, redirect, url_for, render_template, make_response, Response, jsonify, session, current_app
import sys
sys.path.append('../')
from flask_sockets import Sockets
import json
import time
api_blueprint = Blueprint('api_blueprint', __name__)
@sockets.route('/update_status')
def echo_socket(ws):
message = ws.receive()
while not ws.closed:
ws.send(json.dumps({"data":message}))
time.sleep(1)
if ws.closed:
session.clear()
print("session cleared")
sockets = Sockets(current_app)
sockets.register_blueprint(api_blueprint, url_prefix=r"/api")
The main run.py
file where the app
context is available, is started with this:
if __name__ == "__main__":
from gevent import pywsgi
from geventwebsocket.handler import WebSocketHandler
server = pywsgi.WSGIServer(('0.0.0.0', 15080), app, handler_class=WebSocketHandler)
print(server)
server.serve_forever()