Kristian Kristensen’s Blog

ErlChat – A Simple Chat Server Written In Chicago Boss, A Web Framework For Erlang

Posted in Code,Erlang by Kristian Kristensen on the December 13th, 2011

Recently I’ve been exploring Erlang and its web frameworks. As part of this exploration I found Chicago Boss. This blog post is a pointer into the simple chat server I built using Erlang and Chicago Boss.

Jordan Orelli and Seth Murphy from Hacker School built Chatify as a demo application for Brubeck:

Brubeck is a flexible Python web framework that aims to make the process of building scalable web services easy.

Chatify is a simple chat application built with Brubeck as the backend and HTML and Javascript as the front end.
I decided to reimplement the backend in Chicago Boss and reuse the front-end. The result is Erlchat.

Here’s the main page of Erlchat, where you enter your nickname before logging into the chat:

Click to View in Fullsize - ErlChat Main Page

Bert and Ernie chat’s away:

Click to View in Fullsize - ErlChat Chat Screen 1

They’re loving it!

Click to View in Fullsize - ErlChat Chat Screen 2

The code is really simple. Mostly because the required parts for building a chat server is built into Chicago Boss in the form of a message queue abstraction. However, the reason it works is because of Erlangs ability to scale out. Each call to retrieve messages is a long polling HTTP call, and hence blocks a connection. Since Erlang scales to many thousands of processes and Chicago Boss takes advantage of that, it really isn’t a problem.

The following function gets called by the client when he wishes to retrieve the messages that have occurred in Channel since his last retrieveal (LastTimestamp). It blocks on the call to boss_mq:pull.

receive_chat('GET', [Channel, LastTimestamp]) ->
    {ok, Timestamp, Messages} = boss_mq:pull(Channel, list_to_integer(LastTimestamp)),
    {json, [{timestamp, Timestamp}, {messages, Messages}]}.

Sending a message is a simple HTTP POST that creates a new message and pushes it on to the Channel message queue. It uses the utility method seen below.

send_message('POST', [Channel]) ->
    create_and_push_message(Channel, list_to_binary(Req:post_param("message")), Req:post_param("nickname")),
    {output, "ok"}.

create_and_push_message(Channel, Message, Username) ->
    NewMessage = message:new(id, Message, Username, erlang:localtime()),
    boss_mq:push(Channel, NewMessage).

Check out the README as well as the source. It’s all up on Github.

  • If you like my writing you should subscribe to my RSS feed.

    Leave a Reply

    You must be logged in to post a comment.