Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pushing data once a URL is requested

Tags:

python

wsgi

Given, when a user requests /foo on my server, I send the following HTTP response (not closing the connection):

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

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

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

When the user goes to /bar (which will send 204 No Content so the view doesn't change), I want to send the following data in the initial response.

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

bar

How would I get the second request to trigger this from the initial response? I'm planning on possibly creating a fancy [engines that support multipart/x-mixed-replace (currently only Gecko)]-only email webapp that does server-push and Ajax effects without any JavaScript, just for fun.

like image 988
Eli Grey Avatar asked Apr 05 '10 02:04

Eli Grey


People also ask

Can a server PUSH to client?

Server Push is where the server pushes a resource directly to the client without the client asking for the resource. The server is making an assumption here that pushing the resource is desirable. Pushing a cacheable resource can be risky, as the browser might already have the resource and the push can be redundant.

How to send data in GET method?

get( url, [data], [callback], [type] ) method loads data from the server using a GET HTTP request. data − This optional parameter represents key/value pairs that will be sent to the server. callback − This optional parameter represents a function to be executed whenever the data is loaded successfully.


3 Answers

No complete answer, but:

In your question, you're describing a Comet-style architecture. Regarding support of Comet-style techniques in Python/WSGI, there is a StackOverflow question, which talks about various Python servers with support for long-running requests a la Comet.

Also interesting is this mail thread in the Python Web-SIG: "Could WSGI handle Asynchronous response?". In May 2008, there was a broad discussion in the Web-SIG about the topic of asynchronous requests in WSGI.

A recent development is evserver, a lightweight WSGI server, which implements the Asynchronous WSGI extension proposed by Christopher Stawarz in the Web-SIG in May 2008.

Finally, the Tornado web server supports non-blocking asynchronous requests. It has a chat example application using long polling, which has similarities with your requirements.

like image 110
flight Avatar answered Sep 23 '22 00:09

flight


If the problem is to pass some command from /bar application to /foo application and you are using some servlet-like approach (the Python code is loaded once and not for each request as in CGI), you can just change some class property of the /foo application and be ready to react to the change in the /foo instance (by checking the property state).

Obviously the /foo application should not return right after the first request and yield content line by line.

Thought this is just theory, I have not tried that myself.

like image 44
newtover Avatar answered Sep 25 '22 00:09

newtover


I have created some small example (just for fun, you know :))

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.

The idea of a shared variable and thread synchronization (using condition variable object) is based on the fact that WSGI server provided by CherryPyWSGIServer is threaded.

like image 30
Messa Avatar answered Sep 26 '22 00:09

Messa