【问题标题】:Simpliest python long polling最简单的python长轮询
【发布时间】:2013-01-05 01:57:14
【问题描述】:

我在 python 中看到了一些关于长轮询的线程,但我的问题不是使用一些额外的工具包,如龙卷风等。 我有js客户端。它将请求发送到我的 /longpolling 页面并等待响应。一旦它得到响应或超时,它就会发送新的。这运作良好。 我的 /longpolling 处理程序是一个函数:

currentTime = datetime.datetime.now()
lastUpdate = datetime.datetime.strptime(req.GET["ts"], "%Y-%m-%dT%H:%M:%S.%f")
response = {
    "added": [],
    "updated": [],
    "deleted": []
}
while (datetime.datetime.now() - currentTime).seconds < 600:
    time.sleep(2)
    now = datetime.datetime.now()
    #query = Log.objects.filter(time__range = (lastUpdate, now))
    query = Log.objects.raw("SELECT * FROM ...log WHERE time BETWEEN %s and %s", [lastUpdate, now])
    exist = False
    for log in query:
        exist = True
        type = {
            NEW: "added",
            UPDATED: "updated",
            DELETED: "deleted"
        }[log.type]
        response[type].append(json.loads(log.data))
    if exist:
        response["ts"] = now.isoformat()
        return JsonResponse(response)
response["ts"] = datetime.datetime.now().isoformat()
return JsonResponse(response)

在 10 分钟内每 2 秒我想检查数据库中的新日志实例以通知 js 客户端。 我尝试通过 phpMyAdmin 手动插入日志记录,但下一个 Log.objects.filter(time__range = (lastUpdate, now)) 返回空 QuerySet。我从 .query attr 复制原始查询,它看起来像:

SELECT ... FROM ... 2013-01-05 03:30:36 和 2013-01-05 03:45:18 之间的时间

所以我引用了 2013-01-05 03:30:36 和 2013-01-05 03:45:18 并通过 phpMyAdmin 执行了这个 SQL,它返回了我添加的记录。 我试过了:

query = Log.objects.filter(time__range = (lastUpdate, now))

query = Log.objects.raw("SELECT * FROM ...log WHERE time BETWEEN %s and %s", [lastUpdate, now])

用于登录 query.iterate():

但它总是返回一个空的 QuerySet 而不是我添加的记录。 我以为有一些缓存,但是在哪里? 或者问题是我在 while True: 循环执行之前插入新记录?或者也许有一些线程保护?为什么 phpMyAdmin 看到记录但 django 没有? 请帮帮我,我卡住了。

【问题讨论】:

  • 尝试使用 django 代码在查询之前插入一个日志条目。您是否有可能不小心将 phpMyAdmin 指向与您指向 django 的数据库不同的数据库?调试和生产数据库之间的区别还是什么?
  • 在之前插入新的日志条目的好主意,我会尝试回答。不,它们连接到同一个数据库。
  • Okey,所以如果我在查询之前创建新的日志条目,我会在 QuerySet 中获取它,它会正确添加到响应对象并响应客户端。在该客户端按预期发送新请求之后,那现在呢?

标签: python django multithreading long-polling ajax-polling


【解决方案1】:

我没有遇到这个问题,所以我不确定。根据@DanielRoseman 在您在 cmets 中链接的线程中的回答,您也许可以这样做:

with transaction.commit_on_success():
    query = Log.objects.raw("SELECT * FROM ...log WHERE time BETWEEN %s and %s", [lastUpdate, now])

不过,您似乎更有可能必须将插入日志条目的行包装在 commit_on_success 装饰器中。我不确定日志条目在您的代码中的哪个位置插入。

【讨论】:

    猜你喜欢
    • 2014-03-14
    • 2017-08-09
    • 2011-04-07
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 2012-10-18
    • 2013-08-08
    • 2011-10-13
    相关资源
    最近更新 更多