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来启动

Flask+flask-socketio+jsonrpc组合配置避坑的更多相关文章

  1. ngnix使用超时响应时间配置避坑一例

    ngnix的超时响应时间配置得比tomcat的spring mvc响应时间还小,悲剧就发生了,生产环境还不易发现. 就好比定制固定木柜没考虑进门的尺寸,横竖斜都进不去,太悲剧了.哈哈哈,以此为鉴!~

  2. 05 flask源码剖析之配置加载

    05 Flask源码之:配置加载 目录 05 Flask源码之:配置加载 1.加载配置文件 2.app.config源码分析 3.from_object源码分析 4. 总结 1.加载配置文件 from ...

  3. 【基因组注释】RepeatMasker和RepeatModeler安装、配置与运行避坑

    目录 1.conda安装 2.配置RepBase 3.RepeatMasker避坑 4.RepeatProteinMask避坑 5.RepeatModeler避坑 6.自定义重复序列库 后记 1.co ...

  4. python三大web框架Django,Flask,Flask,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架

    Python几种主流框架 从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python We ...

  5. 15. Go 语言“避坑”与技巧

    Go 语言"避坑"与技巧 任何编程语言都不是完美的,Go 语言也是如此.Go 语言的某些特性在使用时如果不注意,也会造成一些错误,我们习惯上将这些造成错误的设计称为"坑& ...

  6. day92:flask:flask简介&基本运行&路由&HTTP请求和响应

    目录 1.Flask简介 2.关于使用flask之前的准备 3.flask的基本运行 4.flask加载配置 5.传递路由参数(没有限定类型) 6.传递路由参数(通过路由转换器限定路由参数的类型) 7 ...

  7. 双刃剑MongoDB的学习和避坑

    双刃剑MongoDB的学习和避坑 MongoDB 是一把双刃剑,它对数据结构的要求并不高.数据通过key-value的形式存储,而value的值可以是字符串,也可以是文档.所以我们在使用的过程中非常方 ...

  8. Windows环境下Anaconda安装TensorFlow的避坑指南

    最近群里聊天时经常会提到DL的东西,也有群友在学习mxnet,但听说坑比较多.为了赶上潮流顺便避坑,我果断选择了TensorFlow,然而谁知一上来就掉坑里了…… 我根据网上的安装教程,默认安装了最新 ...

  9. spring-boot-starter-thymeleaf 避坑指南

    第一步:pom配置环境 先不要管包是做什么的 总之必须要有 否则进坑 <!--避坑包--> <dependency> <groupId>net.sourceforg ...

  10. MyBatis 一级缓存避坑

    MyBatis 一级缓存(MyBaits 称其为 Local Cache)无法关闭,但是有两种级别可选: package org.apache.ibatis.session; /** * @autho ...

随机推荐

  1. Linux中vim快捷键+vim报错解决

    vim快捷键+vim报错解决 vim 快捷键 编辑器 ​ yum -y install vim ​ 快捷键: 视图模式: 0 Home ^ 快速移动光标到行首 $ End 快速移动光标到行尾 u 撤销 ...

  2. (Redis基础教程之九) 如何在Redis中使用Sorted Sets

    介绍 Redis是一个开源的内存中键值数据存储.在Redis的,排序集合类似于一个数据类型集在这两者都是串的非重复的组.不同之处在于,已排序集中的每个成员都与一个分数相关联,从而可以从最小分数到最大分 ...

  3. Spring对JTA的支持

    引言: Spring 通过AOP技术可以让我们在脱离EJB的情况下享受声明式事务的丰盛大餐. 通过配合使用ObjectWeb的JOTM开源项目,在不需要Java EE应用服务器的情况下,Spring也 ...

  4. Fork/Join框架之Fork、Join操作

    Fork Fork就是一个不断分枝的过程,在当前任务的基础上长出n多个子任务. 当一个ForkJoinTask任务调用fork()方法时,当前线程会把这个任务放入到queue数组的queueTop位置 ...

  5. vue父组件向子组件传递一个对象,使用一个对象绑定多个 prop

    如果你想要将一个对象的所有属性都当作 props 传入,你可以使用没有参数的 v-bind,即只使用 v-bind 而非 :prop-name.例如,这里有一个 post 对象: export def ...

  6. Blazor 组件库 BootstrapBlazor 中Modal组件介绍

    组件说明 Model组件是一个模态框组件,可以弹出一个对话框,适合需要定制性更大的场景. 它的样子如下: 其html代码为: <div class="modal-content&quo ...

  7. 2024御网杯信息安全大赛个人赛wp_2024-11-27

    MISC题解 题目附件以及工具链接: 通过网盘分享的文件:御网杯附件 链接: https://pan.baidu.com/s/1LNA6Xz6eZodSV0Io9jGSZg 提取码: jay1 --来 ...

  8. springboot 参数注解 注入参数

    什么时注解参数 说明 我们在 使用spring mvc 的时候会使用这样的注解 @ResponseBody 这样,spring mvc 会将 客户端传来的数据,自动构建成 相应类型的对象. 有些情况下 ...

  9. 编译器-FIRST集合(补充:左递归)

    上一篇中实现的First函数没有考虑左递归,在这对此说明和实现 1.立即左递归 A -> Ab|a 1.两步或两步以上产生的左递归 A -> Bc|a B -> Ab|d 前面的实现 ...

  10. uni-app开发的app版本更新

    标签: uni-app 版本更新 前情 uni-app是我很喜欢的跨平台框架,它能开发小程序,H5,APP(安卓/iOS),对前端开发很友好,自带的IDE让开发体验也很棒,公司项目就是主推uni-ap ...