我正在建立一个小瓶子和基于pyhon的应用程序,我的主要功能是基于websockets。我发现我无法在websockets事件的事件处理程序中修改sesssion的值(我使用flask-socketio
)因为flask将其会话存储在客户端。因此,作为扩展程序的作者,我安装flask-kvsession
以在基于redis
的后端的服务器端存储会话。
我按照提出的说明http://pythonhosted.org/Flask-KVSession/,但问题仍然存在。所以我创建了一个小程序来向你展示我正在谈论的内容。
# main.py
from flask import Flask, session, render_template
from flask.ext.socketio import SocketIO
from pprint import pprint
import redis
from flask_kvsession import KVSessionExtension
from simplekv.memory.redisstore import RedisStore
store = RedisStore(redis.StrictRedis())
app = Flask(__name__)
app.debug = True
app.secret_key = 'secret!'
KVSessionExtension(store, app)
socketio = SocketIO(app)
@app.route('/')
def index():
pprint(session)
return render_template("client.html")
@socketio.on('connect')
def handle_connect(message):
session['debug'] = 'debug'
pprint(session)
if __name__ == "__main__":
socketio.run(app)
<!-- templates/client.html -->
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/
socket.io/0.9.16/socket.io.min.js"></script>
<script type="text/javascript">
var sock = io.connect('http:localhost:5000');
sock.emit('connect', {debug: 'debug'});
</script>
</body>
</html>
这是werkzeug debuging服务器的输出:
* Running on http://127.0.0.1:5000/
* Restarting with reloader
<KVSession {}>
127.0.0.1 - - [2014-07-04 21:25:51] "GET / HTTP/1.1" 200 442 0.004452
<KVSession {'debug': 'debug'}>
<KVSession {}>
127.0.0.1 - - [2014-07-04 21:26:02] "GET / HTTP/1.1" 200 442 0.000923
<KVSession {'debug': 'debug'}>
我希望第二次访问该页面时,会话的内容为'debug': 'debug'
,但事实并非如此。
以下是我在运行此应用时在redis服务器上发生的事情:
127.0.0.1:6379> MONITOR
OK
1404498351.888321 [0 127.0.0.1:38129] "GET" "136931c509f674e3_53b6e25b"
1404498352.073011 [0 127.0.0.1:38129] "GET" "136931c509f674e3_53b6e25b"
1404498362.455320 [0 127.0.0.1:38129] "GET" "136931c509f674e3_53b6e25b"
1404498362.612346 [0 127.0.0.1:38129] "GET" "136931c509f674e3_53b6e25b"
如您所见,会话的值被访问了4次,但从未被修改过。 那么,我该怎么做才能修复这个错误呢?
答案 0 :(得分:1)
正如文档中所解释的,Flask-SocketIO不会将会话写回会话存储,它只是将它们保存在内存中并可供套接字处理程序访问。
如果您希望服务器端会话的更改持续存在并可供常规HTTP客户端使用,则必须在进行这些更改后自行保存会话。我自己还没有对此进行测试,但我认为这样做:
session.modified = True
app.save_session(session, make_response('dummy'))
请注意save_session()
获得虚拟回复。只有在此之前已在常规HTTP调用中建立会话时,此方法才有效。显然,不会使用上面的代码创建新会话,因为响应将被丢弃并且永远不会到达客户端。