结合有两种方式:
第一种:
首先flask和gevent-websocket联合使用,brain.py
import gevent
from geventwebsocket import WebSocketError
from sqlalchemy import func
from brain import app, logger
from flask import request
import json
app = Flask(__name__)
@app.route('/websocket')
def answer():
"""
使用flask的路由来获取webscoket
:return:
"""
web_socket = request.environ.get('wsgi.websocket')
on_open(web_socket, openid)
while True:
try:
# 接收消息
message = web_socket.receive()
on_message(web_socket, message, openid)
except WebSocketError as e:
logger.info('WebSocketError %s', str(e))
on_close(openid)
# logger.info('close client:%s' % openid)
return 'Error, connection closed!!!'
接下来是与gunicorn结合
websocket_app.py
from werkzeug.contrib.fixers import ProxyFix
from brain import app
app.wsgi_app = ProxyFix(app.wsgi_app)
rungunicord.sh
gunicorn -w 10 --threads 30 -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -b 0.0.0.0:5073 -D --timeout 15 websocket_app:app
这是第一种。
第二种:
首先flask和gevent-webscoket结合使用 chat.py
from __future__ import print_function
import json
from flask import Flask, render_template
from werkzeug.debug import DebuggedApplication
from geventwebsocket import WebSocketServer, WebSocketApplication, Resource
flask_app = Flask(__name__)
flask_app.debug = True
class ChatApplication(WebSocketApplication):
def on_open(self):
print("Some client connected!")
def on_message(self, message):
if message is None:
return
def on_close(self, reason):
print("Connection closed!")
@flask_app.route('/')
def index():
return 'hello'
resource = Resource([('^/chat', ChatApplication), ('^/.*', DebuggedApplication(flask_app))])
然后与gunicorn结合使用 rungunicorn.sh
gunicorn -w 10 -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -b 0.0.0.0:5075 --timeout 15 gun_work:resource
两种方法都可以运行使用,但我一般是用第一种,第二种的路由需要自己配置,第一种可以使用flask的路由,更简洁好用。
算是我自己一点一点查文档,花了挺长时间解决的,想把这个写下来,给别人参考
还发现其中有一个问题,gunicorn和gevent-webscoket结合使用,如果设置多个work,那么就无法正确的共享全局变量。这是因为gunicorn每个work都有一个单独的内存,是相互独立的。
尝试了很多方式都无解,如果有人能解决这个问题希望能告知一下思路。目前是以1个work ,多个线程来使用的。