Flask+flask-socketIO+jsonrpc這種組合能被我套出來也是離譜,事先宣告:出現這種組合是因為本人之前對flask框架的使用僅限于flask+jsonrpc,所以導致這種情況出現,其實flask還可以加Flask-Restful實作,至于如何使用全憑讀者根據業務需求自行裁決,
我之隨意寫這篇文章是有原因的,就是部署的時候由于組態檔會給自己埋下許多坑,百度查不到具體的解決方法,只能自己一點點摸索
一、起源
說起這個就很danTeng,剛離開北京來到成都,就職于一家四十多人的小外包公司,大部分業務是給高校和國家電網做系統,一個專案功能迭代,要實作一個聊天室功能,當時我就在想,釘釘會議,騰訊會議,這種工具不香嗎?實在不行你開個直播間加個鎖,本身就是一所學校里面的管理類系統,弄個無聲聊天室,真是離大譜,
沒辦法,甲方爸爸的要求不能不做,然后任務就落到了我的頭上,以前也沒做過聊天室,那就各種找資料了解相關方面的知識,起初我最先想到的是tornado框架,畢竟處理高并發,自帶websocket的輕量級框架,但是我后來跑去問我以前的老師,他說也可以用socketIO來實作,我聽從了這個建議,然后就組合了出來Flask+flask-socketio+jsonrpc,因為里面還有不需要長連接的功能,
二、組態檔部分
初版本的全坑組態檔,一個又一個的坑,一次又一次的填,唉,,,
我把flask+flask-socketio+jsonrpc組合成下面這種__init__.py的組態檔,然后在manage.py中呼叫執行
init_app函式中的引數是詳細的資料庫和日志的配置資訊引數,我以檔案的方式寫在config的dev和prod里面了,這些不重要,
全坑套餐配置如下(模擬的,非專案配置):
# __init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from flask_jsonrpc import JSONRPC
from flask_cors import CORS
from .settings.dev import DevConfig
from .settings.prod import ProdConfig
from .settings import redis
from .libs.log import init_log
from flask_socketio import SocketIO
config = {
"dev": DevConfig,
"prod": ProdConfig,
}
db = SQLAlchemy()
# 初始化jsonrpc模塊
jsonrpc = JSONRPC(service_url='/api')
async_mode = "eventlet"
# async_mode = None
socketio = SocketIO(logger=True, engineio_logger=True)
app = Flask(__name__, static_url_path="/static", static_folder="../static", template_folder="../templates")
def init_app(configName):
"""初始化函式"""
# 設定配置類
Config = config[configName]
# 加載配置
app.config.from_object(Config)
# redis初始化
redis.init_app(app, decode_responses=True)
# 資料庫初始化
db.init_app(app)
# 實體化socketIO物件
socketio.init_app(app=app, async_mode=async_mode, cors_allowed_origins='*')
# 使用終端腳本工具啟動和管理flask
manager = Manager(app)
# 資料庫遷移工具
# 啟用資料遷移工具
Migrate(app, db)
# 添加資料遷移的命令到終端腳本工具中
manager.add_command('db', MigrateCommand)
# 日志初始化
init_log(Config)
# 初始化藍圖
from .urls import init_url
init_url(app)
# 初始化json-rpc
jsonrpc.init_app(app)
# 跨域資源共享
CORS(app, resources={r"/api/*": {"origins": "*"}})
# 添加socketIO命令到終端腳本工具中
@manager.command
def run():
socketio.run(app=app, host='127.0.0.1', port=9000, use_reloader=False)
return manager
# manage.py
from application import init_app
app = init_app("dev")
"""加載模型"""
from application.apps.room.models import *
from application.apps.vote.models import *
if __name__ == '__main__':
app.run()
全坑套餐:
- 此方法僅能在windows系統跑起來,而且想flask和flask-socketio都跑起來需要使用命令:python manage.py run來執行
- 在部署的時候就遇到了大坑因為部署需要用到Gunicorn來部署,無論如何啟動愣是報錯不執行,后來我把:@manager.command注釋了就能執行了
# 配置片段是這樣的
# 跨域資源共享
CORS(app, resources={r"/api/*": {"origins": "*"}})
# 添加socketIO命令到終端腳本工具中
# @manager.command
# def run():
socketio.run(app=app, host='127.0.0.1', port=9000, use_reloader=False)
return manager
但是在windows上跑會有問題
于是我便分析組態檔,查找相關檔案發現
在執行 python manage.py runserver 的時候,如果命令不是flask-script的提供的其他命令的話,就會執行flask實體的run方法, 實質上,就是 Flask(__name__).run()
而flask-script就是監測有沒有收到自己的命令,雖然flask-script也會代理flask的APP, 但是flask-script的物件并不等同與flask的實體,所以提供給gunicorn的還必須得是flask的app
所以改進方法去除flask-script:
這里還存在一個之前存在的坑就是eventlet這個組建的添加方法,之前未添加
# __init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_jsonrpc import JSONRPC
from flask_cors import CORS
from .settings.dev import DevConfig
from .settings.prod import ProdConfig
from .settings import redis
from .libs.log import init_log
from flask_socketio import SocketIO
import eventlet
eventlet.monkey_patch()
config = {
"dev": DevConfig,
"prod": ProdConfig,
}
db = SQLAlchemy()
# 初始化jsonrpc模塊
jsonrpc = JSONRPC(service_url='/api')
async_mode = "eventlet"
# async_mode = None
socketio = SocketIO(logger=True, engineio_logger=True)
app = Flask(
__name__,
static_url_path="/static",
static_folder="../static",
template_folder="../templates"
)
def init_app(configName, flask_app):
"""初始化函式"""
# 設定配置類
Config = config[configName]
# 加載配置
flask_app.config.from_object(Config)
# redis初始化
redis.init_app(flask_app, decode_responses=True)
# 資料庫初始化
db.init_app(flask_app)
# 實體化socketIO物件
socketio.init_app(app=flask_app, async_mode=async_mode, cors_allowed_origins='*')
# 日志初始化
init_log(Config)
# 初始化藍圖
from .urls import init_url
init_url(flask_app)
# 初始化json-rpc
jsonrpc.init_app(flask_app)
# 跨域資源共享
CORS(flask_app, supports_credentials=True)
socketio.run(app=flask_app, host='127.0.0.1', port=9000, use_reloader=False)
# return manager
return flask_app
# manage.py
from application import init_app, app, socketio
app = init_app("dev", app)
"""加載模型"""
from application.apps.room.models import *
from application.apps.vote.models import *
if __name__ == '__main__':
socketio.run(app=app, use_reloader=False)
關鍵就在于去除flask-script的使用,這樣linux作業系統中部署的時候就能使用Gunicorn來啟動
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/380184.html
標籤:Python
