Labs

  1. Trainspotting
  2. CCHAT
  3. A-mazed

Lab 2: CCHAT

Deadlines

Lab description

In this lab, you will build a simple text-based messaging system called CCHAT. CCHAT is very much inspired by IRC, an old but still valid standard designed for group discussions. For simplicity, your implementation of CCHAT is not going to use IRC’s protocol or low-level TCP/IP communication. Instead, it will leverage Erlang’s processes and message passing features.

Programming language

This lab assignment must be developed in Erlang.

How to install Erlang/OTP in your computer.

Overview

The video below shows how your implementation of CCHAT should work.

Erlang functions

Chat commands

Architecture

CCHAT uses a client/server architecture. It consists of a client part, which runs the GUI and a client process, and a server, which hosts the chat channels.

The GUI/client protocol

The protocol between the GUI and the client process is fixed. By following the protocol, you will be able to use the GUI without knowing its internal implementation details. In addition, we will test your code assuming that your client process follows the protocol. If you do not follow it, your code will not pass the tests (see the test section below) and your submission will be immediately rejected.

The GUI sends a message requesting some operations. The client either replies with the atom ok, meaning the operation succeeded:

Alternatively, the client replies with the tuple {error, Atom, Text}, denoting that something went wrong while processing the request (see the Error Handling section below):

Supported operations

Error handling

Assignment

Your assignment is to implement the chat server described here, based on the skeleton available below in the code skeleton section.

Successful solutions require that you do the following:

Submission:

Code skeleton

Download the skeleton code package here

The package conists of the following files. Do not edit (or submit) the ones highlighted in red!

Compilation

After you have downloaded the skeleton code, compile everything with the command:

make all

You can then open the Erlang shell (erl) and start a client with cchat:client(). You should be able to open up chat windows, but users will not able to communicate because most functions are not implemented.

Test cases

We provide some unit tests which check the basic functionality of your solution. All unit tests are contained in the file lib/test_client.erl and are run using EUnit. We have created entries in the Makefile to make life easier for you. To run these tests, simply execute the following:

make -s run_tests

If your submission fails any of the tests, it is a good indication that your solution does not work correctly. However even if you pass all of the tests, that is not a guarantee that your submission will be accepted.

Turning off color codes in test suite

If you don’t have a color-enabled terminal, you will see a lot of ugly color codes in your test output. You can disable these by commenting out the colour function in lib/test_client.erl and replacing it with:

colour(Num,S) -> S.

Tips

Ref = make_ref(),
Pid ! {request, self(), Ref, {message_receive, Channel, Nick, Msg}},
receive
  {result, Ref, Data} -> ...
end
io:fwrite("~p~n", [S])
make && erl -eval "cchat:server(), cchat:client(), cchat:client()."
make && erl -eval "eunit:test({test, test_client, message_throughput_test}), halt()."

Distinction assignment

The distinction assignment will extend of the functionality of the chat and, if implemented correctly, is worth 2 points.

By default, every client gets a random nick. This can be changed with the command /nick newnick, for which a basic implementation has been provided. But what happens if two clients choose the same nick? As a distinction assignment, you should disallow this. In other words, when a user tries to change their nick, make sure it is not already taken before allowing the user to change it! You can return the error atom nick_taken when this is the case. (You do not need to handle the case when the initial random nick collides with an existing nick.)

Menu