Tuesday, November 20, 2012

[Mongrel2] How to write a handler for mongrel2 web server

Mongrel2 is an application, language, and network architecture agnostic web server that focuses on web applications. The most powerful functionality is to use Handler to deal with ZeroMQ message.
There are already some articles talking about Handler and how to get started, for instance:
http://www.ioncannon.net/programming/1384/example-mongrel2-handler-in-ruby/
http://brubeck.io/demos.html

I almost studied 2 days to understand the usage of handler and try a simple handler to respond the request, and finally I finished. So, in this article, I will give a concept about Mongrel2 web server and a simple example.


  • From this diagram, you will quickly realize how the mongrel2 web server works with your handler by what kind of zeromq communication type.
  • Second, I will give the handler example in details:
The conf file ==> mongrel2.conf
brubeck_handler = Handler(
    send_spec='tcp://127.0.0.1:9999',
    send_ident='34f9ceee-cd52-4b7f-b197-88bf2f0ec378',
    recv_spec='tcp://127.0.0.1:9998',
    recv_ident='')

media_dir = Dir(
    base='media/',
    index_file='index.html',
    default_ctype='text/plain')

brubeck_host = Host(
    name="localhost",
    routes={
        '/media/': media_dir,
        '/handlers': brubeck_handler})

brubeck_serv = Server(
    uuid="f400bf85-4538-4f7a-8908-67e313d515c2",
    access_log="/log/mongrel2.access.log",
    error_log="/log/mongrel2.error.log",
    chroot="./",
    default_host="localhost",
    name="brubeck test",
    pid_file="/run/mongrel2.pid",
    port=6767,
    hosts = [brubeck_host]
)

settings = { "zeromq.threads": 1 }

servers = [brubeck_serv]


Load the conf file to mongrel2
> m2sh load -config mongrel2.conf -db the.db

Run the mongrel2 web server
> m2sh start -db the.db -host localhost

Run the simple handler source code ( in Python ) ==> simple_handler.py
> python simple_handler.py

#!/usr/bin/env python
import zmq

ctx = zmq.Context()
pull = ctx.socket(zmq.PULL)
pull.connect("tcp://127.0.0.1:9999")
pub = ctx.socket(zmq.PUB)
pub.connect("tcp://127.0.0.1:9998")

while True:
    msg = pull.recv()
    print msg
    sender_uuid, client_id, request_path, request_message = msg.split(" ", 4)
    ret_content = "Hi...This is Danny..."
    ret_msg = '%s 1:%s, HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n%s' %
    (sender_uuid, client_id , ret_content.__len__(), ret_content)
    pub.send(ret_msg, 0)




Use curl to test it and will get the result as follows:
> curl http://localhost:6767/handlers
Hi...This is Danny...



2 comments:

Thomas Backlund said...

Awesome! So simple and complete example! Love it! Thanks!

TeYen (Danny) said...

Thank you, Thomas.