0

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()
lennyklb
  • 1,307
  • 2
  • 15
  • 32

1 Answers1

2

Hi Lennart Kloppenburg,

Try to put the @play_socket.route('/status_ping') blueprint route before sockets = Sockets(app).

The following works for me and I can talk to the ping websocket on /play/status_ping:

from flask import Blueprint, Flask, request, abort, redirect, url_for, render_template, make_response, Response, jsonify, session
from flask_sockets import Sockets
import json

play = Blueprint('simple_page', __name__)
play_socket = Blueprint('simple_page2', __name__)

@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)

app = Flask(__name__)
sockets = Sockets(app)
app.register_blueprint(play, url_prefix=r"/play")
sockets.register_blueprint(play_socket, url_prefix=r"/play")
  • 1
    Thanks Tomas. For modularity, I'm moving my blueprints to different folders (and thus files) so I'm not entirely sure how to structure it properly. See the edit I'm making, I tried to mimic your advice but it's not working yet (same issue). – lennyklb May 11 '17 at 09:52
  • I'm also facing same issue, did you figure out the solution? – user1501382 Aug 15 '17 at 06:44