Skip to content


Subversion checkout URL

You can clone with
Download ZIP
rio is a http broker
C Other
Latest commit 504fdaa @felipecruz fix worker shutdown leak


rio - minimalist http server

this project is a work in progress

rio is a minimalist http server that act as broker between browsers and your (python, ruby and others) workers.

If you're looking for similar projects, you should check:

External Dependencies and thanks to the Authors of:

Embedded libraries


Open terminal::

git submodule init
git submodule update


Install CUnit (

Open terminal::

make test


Open terminal::

make debug
sudo valgrind --leak-check=full ./rio


Open terminal::

sudo ./rio

rio will serve your current directory files - (html, js, css, json, jpg, png)

Master -> Workers pattern

This branch will implement the master -> workers pattern.

  • Master - holds the runtime with listen socket, references to workers, catch signals and use zeromq PUB to send workers control messages.

  • Worker - a worker can have different roles. The initial idea is to have one worker reading and writing to external clients (http clients like browsers) and other worker sending and receiving payload from backend workers

Worker support

rio is designed to be plugged with backend workers at runtime, and to communicate really fast with them.

Request format - rio to worker(s)

  • [client_id, method, uri] as int, int, string

Respose format - worker(s) to rio

  • [client_id, content/type, content] as int, string, string

A naive python worker

import zmqpy

    import msgpack
except Exception as e:
    import msgpack_pure as msgpack

c = zmqpy.Context().instance()
receiver = c.socket(zmqpy.PULL)
sender = c.socket(zmqpy.PUB)


count  = 0
while True:
    raw = receiver.recv()
    data = msgpack.unpackb(raw)
    sender.send(msgpack.packb([data[0], '<html><h1>rio</h1></html>']))

A naive ruby worker could look like that

require 'zmq'
require 'msgpack'

context =

worker_socket = context.socket ZMQ::PULL
sender_socket = context.socket ZMQ::PUB

worker_socket.connect "tcp://"
sender_socket.connect "tcp://"

count = 0

while true
    req = MessagePack.unpack worker_socket.recv
    count += 1
    id = req[0]
    uri = req[2]
    rep = MessagePack.pack([id, "<html><h1>RubyWorker #{count}</h1></html>"])
    sender_socket.send rep


  • Finish workers synchronization
  • Send http headers to external workers
  • Refactor client struct - change name and use rio_buffer
  • Implement REAL non-blocking behaviour - check all returns and errnos

send me an email:

Something went wrong with that request. Please try again.