对Flask蓝图和socketio的正确实施感到困惑

时间:2015-04-22 02:20:53

标签: python flask socket.io blueprint flask-socketio

我有一个Flask应用程序,我已经重组以利用蓝图。应用程序运行,除了SocketIO和我的socketio.on事件外,一切似乎都没问题。我从来没有看到SocketIO和网络套接字尝试在Chrome调试器中连接或断开连接所有它曾经说过的待处理。我查看了Flask SocketIO Chat示例here,并得到了一些想法。我将所有活动都移回了我的views.py.我似乎无法弄清楚为什么我的sockio.on事件没有被调用或解雇。这是我的代码。 app.py

from factory import create_app
from flask.ext.socketio import SocketIO

app = create_app()
socketio = SocketIO(app)

factory.py

import logging
from logging.handlers import RotatingFileHandler
from flask import Flask
# from flask.ext.socketio import SocketIO
from flask.ext.login import LoginManager
import os
from celery import Celery

lm = LoginManager()
# socketio = SocketIO() 
lm.login_view = 'main.login'
lm.session_protection = 'strong'

def create_app():
    app = Flask(__name__)
    app.clients = {}
    app.config.from_object(os.environ.get('APP_CONFIG'))  # export APP_CONFIG=settings.Development
    lm.init_app(app)

    from project.main import main as main_blueprint

    app.register_blueprint(main_blueprint)
    # socketio.init_app(app)

    # print app.config['LOGPATH']
    if not os.path.isdir(app.config['LOGPATH']):
        print 'Log dir not found'
        os.makedirs(app.config['LOGPATH'])

    if not os.path.isdir(app.config['UPLOAD_FOLDER']):
        print 'Upload dir not found'
        os.makedirs(app.config['UPLOAD_FOLDER'])

   # See Flask error handling for more info on logging
    file_handler = RotatingFileHandler(app.config['LOGPATH'] + 'my.log', maxBytes=1024 * 1024 * 10, backupCount=20)
    file_handler.setFormatter(logging.Formatter("%(asctime)s - %(name)s - %(levelname)s -%(module)s - %(lineno)d - %(message)s"))
    app.logger.setLevel(logging.DEBUG)
    app.logger.addHandler(file_handler)
    app.logger.debug('Starting My Application')
    # app.logger.debug(socketio)
    return app

def make_celery(app=None):
    app = app or create_app()
    celery = Celery(app.import_name, broker=app.config['CELERY_BROKER_URL'])
    # celery.conf.update(app.config)
    celery.config_from_envvar('APP_CONFIG')

    TaskBase = celery.Task
    class ContextTask(TaskBase):
        abstract = True
        def __call__(self, *args, **kwargs):
            with app.app_context():
                return TaskBase.__call__(self, *args, **kwargs)
    celery.Task = ContextTask
    return celery

主/ _init_.py

from flask import Blueprint

main = Blueprint('main', __name__, template_folder='templates', static_folder='static')
import views
# import events

主/ views.py

from celery import chain
from flask import render_template, request, url_for, jsonify, current_app, session
from . import main
from flask.ext.socketio import emit, disconnect
from ..app import socketio
from flask.json import dumps
from werkzeug.utils import secure_filename, redirect
from flask.ext.login import login_required, login_user, logout_user
from uuid import uuid4
from project.tasks import *

@main.route('/')
# @login_required
def index():
    event_count = 0
    current_app.logger.debug('Loaded homepage')
    current_app.logger.debug(socketio)
    return render_template('index.html',
                           event_count=event_count,
                           http_id=session['http_id'])


# @login_required
@main.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        file = request.files['file']
        websocket_session_id = request.form.get('session')
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(current_app.config['UPLOAD_FOLDER'], filename))
            chain(
                parse.s(filename, session['http_id']),
                create_sphere.s(session['http_id'], websocket_session_id, url_for('main.event', _external=True))
            )()

            # parse.delay(filename, session['http_id'])
                # (filename, session['http_id']),
                # link=create_sphere.s(session['http_id'], websocket_session_id, url_for('main.event', _external=True))
            # )
            # parse.apply_async(chain)

            return jsonify({'status': 'processing CSV'})
        else:
            return jsonify({'status': 'wrong file type'})
    if request.method == 'GET':
        return render_template('upload.html')


@main.route('/clients', methods=['GET'])
def clients():
    return jsonify({'clients': current_app.clients.keys()})


@main.route('/event/', methods=['POST'])
def event():
    print '\n'
    print 'request =', request
    print 'request.json =', request.json
    current_app.logger.debug('task: {t}'.format(t=request.json['task']))
    current_app.logger.debug('success: {s}'.format(s=request.json['success']))
    websocket_id = request.json['websocket_id']
    current_app.logger.debug(websocket_id)
    if request.json['task'] == 'task_sphere' and request.json['success']:
        current_app.logger.debug('successfully parsed CSV data')
        current_app.logger.debug(request)
        websocket_id = request.json['websocket_id']
        http_id = request.json['http_id']
        current_app.logger.debug(websocket_id)
        current_app.logger.debug(http_id)
        # try:
        conn = pymongo.MongoClient(current_app.config['MONGO_URL'])
        db = conn.events
        collection = db['%s' % http_id]
        current_app.logger.debug('Collection: {c}'.format(c=collection))
        ns = current_app.clients.get(websocket_id)

        if ns:
            current_app.logger.debug(ns)
            nodes = dumps(list(collection.find({'type' : 'node'})))
            edges = dumps(list(collection.find({'type' : 'edge'})))
            if nodes:
                ns.emit('insert_nodes', nodes)
            if edges:
                ns.emit('insert_edges', edges)

                # ns.emit('insert_data', dumps(list(collection.find())))
            # return 'ok'
        # except:
        #     print 'Could not connect to MongoDB: %s'
        #     return 'ok'
    return 'ok'


# @lm.user_loader
# def load_user(username):
#     u = main.config['USERS_COLLECTION'].find_one({"_id": username})
#     if not u:
#         return None
#     return User(u['_id'])


@main.route('/login', methods=['GET', 'POST'])
def login():
    error = None
    if request.method == 'POST':
        if request.form['username'] != 'admin' or request.form['password'] != 'admin':
            error = 'Invalid Creds'
        else:
            session['logged_in'] = True
            session['http_id'] = str(uuid4())
            return redirect(url_for('main.login'))

    return render_template('login.html', error=error)


@main.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('main.login'))


def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1] in current_app.config['ALLOWED_EXTENSIONS']

##### Put events here for the time being  #####

@socketio.on('status', namespace='/events')
def events_message(message):
    current_app.logger.debug(message['status'])
    print 'socketio.on: status'
    emit('status', {'status': message['status']})


@socketio.on('disconnect request', namespace='/events')
def disconnect_request():
    print 'socketio.on: disconnect request'
    current_app.logger.debug('DISCONNECT REQUEST')
    emit('status', {'status': 'Disconnected!'})
    disconnect()


@socketio.on('connect', namespace='/events')
def events_connect():
    print 'socketio.on: connect'
    websocket_id = str(uuid4())
    session['websocket_id'] = websocket_id
    current_app.logger.debug(websocket_id)
    current_app.clients[websocket_id] = request.namespace
    emit('websocket_id', {'websocket_id': websocket_id})


@socketio.on('disconnect', namespace='/events')
def events_disconnect():
    print 'socketio.on: diconnect'
    current_app.logger.debug('DISCONNECT')
    del current_app.clients[session['websocket_id']]
    print('Client %s disconnected' % session['websocket_id'])

静态/ JS / application.js中

var namespace = '/events'; // change to an empty string to use the global namespace
var socket = io.connect('http://' + document.domain + ':' + location.port + namespace);
var jared;

var edges;
var nodes;

socket.on('connect', function () {

    console.log('socketio: connect');

});


socket.on('disconnect', function () {

    console.log('socketio: disconnect');
    $('#websocket_id').text('not available');

});


socket.on('websocket_id', function (msg) {

    console.log('updating html elements with correct session', msg.websocket_id);
    $('input[name="session"]').val(msg.websocket_id);
    $('#websocket_id').text(msg.websocket_id);

});


socket.on('insert_nodes', function (msg) {

    //console.log(msg);
    //jared = msg;
    $('#myModal').modal('hide');
    nodes = JSON.parse(msg);
    console.log('here are the nodes', nodes);

    var pcGeometry = new THREE.Geometry();
    for (var i = 0; i < nodes.length; i++) {
        var position = nodes[i].position;
        //console.log(position);
        vector = new THREE.Vector3(position.x, position.y, position.z);
        //console.log(vector);
        pcGeometry.vertices.push(vector);
    }
    //console.log(geometry);

    pcMat = new THREE.PointCloudMaterial();
    pcMat.size = 10;
    pcMat.transparent = true;
    pcMat.blending = THREE.AdditiveBlending;
    pcMat.color = new THREE.Color(0x5555ff);
    pc = new THREE.PointCloud(pcGeometry, pcMat);
    pc.sizeAttenuation = true;
    webGLScene.add(pc);

});

socket.on('insert_edges', function (msg) {

    function getById(id, myArray) {
        return myArray.filter(function (obj) {
            if (obj._id.$oid == id) {
                return obj
            }
        })[0]
    }

    edges = JSON.parse(msg);
    console.log('here are the edges', edges);

    var material = new THREE.LineBasicMaterial({
        opacity: .3,
        blending: THREE.AdditiveBlending,
        transparent: true
    });
    //geometry.vertices.push(start);


    for (var i = 0; i < edges.length; i++) {

        var start = edges[i].start.$oid;
        var start_pos = getById(start, nodes);
        var start_vec = new THREE.Vector3(start_pos.position.x, start_pos.position.y, start_pos.position.z);

        var end = edges[i].end.$oid;
        var end_pos = getById(end, nodes);
        var end_vec = new THREE.Vector3(end_pos.position.x, end_pos.position.y, end_pos.position.z);

        var geometry = new THREE.Geometry();
        geometry.vertices.push(start_vec);
        geometry.vertices.push(end_vec);
        var line = new THREE.Line(geometry, material);
        webGLScene.add(line);

    }

});

socket.on('status', function (msg) {

    console.log('status', msg);

});

0 个答案:

没有答案