dark theme

aMSN2's web frontend

aMSN2 is designed to offer multiple frontends so that it should be able to run on whatever you like. One such frontend is the web frontend.

The primary is not to provide you a website where you'd go and connect to MSN. Instead we want to let you host aMSN2 and run it in your web browser.

It was first designed using a webserver with php. It was working but I thought we could use directly python instead of php and embed directly a small webserver in amsn2-web.

aMSN2's design

Here is how I want to implement it, just like every other frontend:

papyon ↔ amsn2 ↔ the frontend

  • papyon is used to connect to the msn network
  • amsn2 listens to papyon and the frontend making them understand each other.
  • the frontend displays what aMSN2 tells it and tells aMSN2 when the user did something (like clicking on a contact in the contact list)

aMSN2 has an event loop to deal with events from papyon or the frontend. This works nicely for most of the frontends.

But the web is different.

Here is how it was working:

  • If the user clicked on a webpage, your browser (using jQuery) sends directly the query to the webserver. The webserver put the query in a file.
  • aMSN look at that file every 100ms or so. Oh, there's something to process! aMSN2 deals with the event and may ask papyon to do some work.
  • Then an event occured in papyon. aMSN2 gets notified directly. A contact went online. It needs to tell your browser about it. To do that, it writes it to the file.
  • Every now and then, the web frontend asks if there is something new and get that your contact has just came online.

There are some issues here. Having to check every X ms to know if there is something to do isn't great. We have an event loop, let's use it!!

Cherrypy

First, aMSN2 should include directly the webserver and add it to it's event loop so that when the web frontend wants something, it can reply to it right away. I've tried to do that with cherrypy.

I tell my browser to go to http://127.0.0.1:8080/static/amsn2.html. After few seconds, I see in the logs that cherrypy got the query.

It's a static file. It should handle it easily. But I wait and wait again and nothing happens. When I send SIGINT (Ctrl+c) to aMSN2, then the page load correctly!! Even in its own thread, cherrypy is blocking on something.

Here is the code I use to do that:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Root(object):
    def __init__(self, inq, outq):
        self._inq  = inq
        self._outq = outq

    @cherrypy.expose
    def index(self):
        raise cherrypy.HTTPRedirect("static/amsn2.html")

    @cherrypy.expose
    def signin(self, u=None, p=None):
        self._inq.put_nowait(["signin", u, p])

    @cherrypy.expose
    def out(self):
        l = []
        while True:
            try:
                l.append(self._outq.get_nowait())
            except Queue.Empty:
                break;
        return l

current_dir = os.path.dirname(os.path.abspath(__file__))
cherrypy.config.update({'log.error_file': 'amsn2-web-error.log',
                       'log.access_file': 'amsn2-web-access.log',
                       'log.screen': False})

conf = {'/static': {'tools.staticdir.on': True,
        'tools.staticdir.dir': os.path.join(current_dir, 'static')},
       }
cherrypy.quickstart(Root(inq, outq), '/', config=conf)

How I want to handle that issue.

aMSN2 should listen to 127.0.0.1:8080 (or whatever you want). When something happens, it should have a tiny HTTP machine to process the query and act just like the web frontend was like every other frontend. Then we should use “long push”. jQuery sends a query to now what's new. aMSN2's doesn't answer yet but once there is something to tell the frontend, it replies. The browser updates whatever needed based on the answer and send right away a new query to know what's new.

If you want to help me with that, feel free to contact me.

blog comments powered by Disqus

If you enjoyed this article, feel free to Flattr this.