Web2py,多个 Ajax 调用和存储在 MySQL 中的会话变量

Web2py, multiple Ajax calls and session variables stored in MySQL

为了使用 cache.ram 的进度条和 ajax 调用正常工作,需要清理(或只是解锁?)会话。 如果应用程序不使用会话变量传递给其他控制器,那么 session.forget(response) 就足够了。

如果另一方面,应用程序需要会话变量(正如我的应用程序确实需要的那样)- 那么 session.forget 并没有多大用处,因为它阻止了会话变量传输到其他控制器的链。

根据 Anthony 在 Web2Py google 组的另一个 post(进度条和会话)中的建议:

我首先尝试使用 cookie(最大 zlib 压缩 - 级别 9)。 仍然不能满足我的需求......我需要将每个会话超过 10k 传递给其他控制器,并且如书中所述 - 如果会话预计很大(更多比我假设的 4k/cookie)。

所以我正在尝试 session.connect 使用 MySQL 数据库。 我可以看到 table web2py_session_AppName 被填充,我知道 session_data 列是用 cPickle 腌制的。 但是...看起来这一列中的数据,session_data 是加密的,而不仅仅是腌制的。

如何从 MySQL table 中取消 session_data 列中的信息? 我尝试使用 cPickle.loads...按原样使用数据,将数据作为字符串...但它仍然抛出 "bad pickle error"

这是控制器:

def index():
    session.Yawza = 'Yawza from index'
    cache.ram(CacheKeyUID, lambda: 0, 0)
    return dict()

def cache_in_ram():
    for i in range(int(1e5)):
        avoda = int((i/(1e5))*100)
        cache.ram(CacheKeyUID, lambda:avoda, 0)
    session.Yawza = "Yawza from the cache_in_ram"
    redirect(URL('Test'))

def cache_reader():
    return cache.ram(CacheKeyUID, lambda: None, None)

def test():
    return dict(message = 'Long process ended')

以上将仅在第一次使用进度条。在那之后进度条将不起作用(由于多次 ajax 调用锁定) - 除非我手动清除会话或以编程方式执行 session.forget(response)将不幸地消除 session.Yawza。我需要这个 session.Yawza 除了进度条之外的其他目的,在下游的其他控制器中。

添加session.connect(请求,响应,cookie_key='yoursecret',compression_level=9)到我的db.py 有帮助,但仅限于 4k 大小的 cookie。我需要比那更大的饼干。因此,我转向将会话存储在数据库中,在我的例子中是 MySQL 数据库。

在 db.py 中定义了 session.connect(请求、响应、数据库)。我可以在 MySQL 中看到 table web2py_session_AppName 被填充,但我根本无法访问 session.Yawza。 不是来自索引函数,也不是来自 cache_in_ram 函数。

这就是我认为我应该手动解开 session_data 列的原因...以访问必须隐藏在那里的 session.Yawza。

这是 web2py_sessions_MyAppName MySQL table 的 session_data 列中的一小部分示例: gAJjZ2x1b24uZ2xvYmFscwpTZXNzaW9uCnEBfXECVQVZYXd6YXEDVQ1mcm9tIHRleHQgYm9...

我觉得它不像犹太泡菜…… ;-))

为了从多个 ajax 调用中获益,没有会话锁定并且仍然使用会话变量将信息传输到其他控制器,我做了什么或没有做正确的事情?

您可能会考虑是否可以更改 long 运行ning cache_in_ram 函数而无需写入会话。在这种情况下,您可以在该函数的开头调用 session.forget(response),一切都会正常工作,即使使用默认的基于文件的会话(即,无需将会话移动到 cookie 或数据库)。

如果您必须从 cache_in_ram 请求中写入会话,您可以先解锁会话,然后 运行 长循环,然后重新打开会话并将其更新为需要:

def cache_in_ram():
    session.forget(response) # Unlock the session file.
    for i in range(int(1e5)):
        avoda = int((i/(1e5))*100)
        cache.ram(CacheKeyUID, lambda:avoda, 0)
    session.connect() # Re-open/lock the session file.
    session._forget = False # Reverse the "forget" so we can write to the session.
    session.Yawza = "Yawza from the cache_in_ram"
    redirect(URL('Test'))

或者,您可以切换到在数据库中存储会话,这不会进行任何锁定,因此不会导致 Ajax 进度检查被 long-运行ning cache_in_ram请求。在这种情况下,无需手动从数据库中读取和解压会话数据——只需像往常一样使用 session 对象。如果您发现在这种情况下您无法按预期访问会话数据,那么您在设置连接或从会话写入 to/reading 的方式上做错了。你应该post一个单独的问题,显示你的所有代码。