请求URL时推送数据

8 投票
4 回答
2006 浏览
提问于 2025-04-15 21:14

假设当用户在我的服务器上请求 /foo 时,我会发送以下的HTTP响应(连接不会关闭):

Content-Type: multipart/x-mixed-replace; boundary=-----------------------

-----------------------
Content-Type: text/html

<a href="/bar">foo</a>

当用户访问 /bar 时(这个请求会返回 204 No Content,所以页面不会改变),我想在最初的响应中发送以下数据。

-----------------------
Content-Type: text/html

bar

我该如何让第二个请求从最初的响应中触发这个呢?我打算可能会创建一个只支持 [engines that support multipart/x-mixed-replace (目前只有Gecko)] 的邮件网页应用,它可以在不使用任何JavaScript的情况下实现服务器推送和Ajax效果,纯粹是为了好玩。

4 个回答

1

我做了一个小例子(只是为了好玩,你懂的 :)

import threading

num = 0
cond = threading.Condition()

def app(environ, start_response):
    global num

    cond.acquire()
    num += 1
    cond.notifyAll()
    cond.release()

    start_response("200 OK", [("Content-Type", "multipart/x-mixed-replace; boundary=xxx")])
    while True:
        n = num    
        s = "--xxx\r\nContent-Type: text/html\r\n\r\n%s\n" % n
        yield s
        # wait for num change:
        cond.acquire()
        while num == n:
            cond.wait()
        cond.release()


from cherrypy.wsgiserver import CherryPyWSGIServer
server = CherryPyWSGIServer(("0.0.0.0", 3000), app)

try:
    server.start()
except KeyboardInterrupt:
    server.stop()

# Now whenever you visit http://127.0.0.1:3000/, the number increases.
# It also automatically increases in all previously opened windows/tabs.

共享变量和线程同步的想法(使用条件变量对象)是基于这样一个事实:CherryPyWSGIServer 提供的 WSGI 服务器是多线程的。

1

如果你的问题是要把某个命令从 /bar 应用程序传递到 /foo 应用程序,并且你使用的是类似于 servlet 的方法(也就是说,Python 代码只加载一次,而不是像 CGI 那样每次请求都加载),那么你可以直接修改 /foo 应用程序的某个类属性,然后准备好在 /foo 实例中对这个变化做出反应(通过检查这个属性的状态)。

显然,/foo 应用程序在处理完第一次请求后不应该立即返回,而是应该逐行输出内容。

虽然这只是理论上的想法,我自己还没有尝试过。

1

虽然没有完整的答案,但可以分享一些信息:

在你的问题中,你提到的是一种叫做Comet的架构。关于Python/WSGI中对Comet风格技术的支持,有一个StackOverflow的问题,讨论了几种支持长时间请求的Python服务器,这些服务器类似于Comet。

还有一个有趣的邮件讨论线程在Python的Web-SIG中:“WSGI能处理异步响应吗?”。在2008年5月,Web-SIG中对WSGI中的异步请求进行了广泛的讨论。

最近的一个发展是evserver,这是一个轻量级的WSGI服务器,它实现了在2008年5月由Christopher Stawarz在Web-SIG中提出的异步WSGI扩展

最后,Tornado web服务器支持非阻塞异步请求。它有一个使用长轮询的聊天示例应用程序,这与您的需求有相似之处。

撰写回答