CSE 332S: Object Oriented Software Design Laboratory

Spring 2008: Lab 5

Due 11:59pm, April 11th, 2008.

Purpose

This lab will tie together all of the code you have written up to this point into a fully-functional IM client. It will give you some more practice with the Qt graphical toolkit, the STL, and the basic features of the C++ language.

Preparation

Grab a copy of our example client code. Make sure you can compile it. Read over it, and make sure you understand how it works. If there are classes that you've never seen before, then look them up in the documentation, and see what they do and how they are used.

Make a link to our test server code, using this incantation

ln -s ~cse332/public/lab5/IMServer IMServer
Do not make a copy of the executable, since we will be changing this as time goes on. Always run our version, not one you copied earlier. Alternatively, grab a copy of our server code and build a copy yourself. The usual qmake incantations should work. You should only grab a copy of the server if you are not going to use the CEC machines for development.

We also provide a reference client implementation, in ~cse332/public/lab5/IMClient to give you an idea of what we're looking for. Your solution does not have to be exactly the same as ours. You should make design decisions that make sense to you, and try to come up with a better client than our example one.

Open two shells. Run IMServer in one, and IMTestClient (which you should have just built) in the other. Click some of the buttons and discover what it does. Make sure that the two programs can communicate with each other. The server will process requests from the client, and will display some of what it's thinking, to help you debug your own clients. The client that we give you is just a simple example that repeatedly sends "hello" messages.

You can only run one version of the IMServer on a machine at a time. If you try to run more than one, things will go poorly. This means that it might be a bad idea to log into a machine (like grid) remotely to run the server, since there may be other cse332 students already running one. The best idea is to either run it on a machine you're sitting at in the Linux lab, or to run it on your own linux box.

Assignment

  1. The first part of this lab will involve setting up a connection to the server, and communicating with some "personalities" that it has. This will help you debug your code, and make sure that communications are happening as expected before we start sending messages to other clients. Take a minute and read the example client code. You will be using this code as the core of your networking system for your client.
  2. Modify your Message classes to include a destination tag, which specifies where the message should be sent.
  3. Further modify your Message classes to make sure that they do not contain newlines, either in the tag bodies, or between the tags. We're being a little cheap with the networking parsing in the server, and this will break our code. The main place to watch for this is when extracting text from an QTextEdit, which appends a newline to the end of the text you type.
  4. Integrate the networking code with the IM client GUI that you created in a previous lab. The executable should have the following features:
    1. It should take one command line argument, specifying the destination of all messages. For now, we'll assume that you're only going to be sending messages to one destination per session.
    2. When you start up the interface, you should send a "hello" message to the destination server. This will inform the server that you are there, and ready to talk. If you do not send this message, the server will ignore you.
    3. The server will reply with a "hello" message, addressed to you. You should not send any additional messages until you receive this reply, and verify its sender field.
    4. When you quit, you should send a "goodbye" message to the server, and wait for the reply (also a "goodbye" message). You should not exit the program until this reply arrives.
    5. Typing in text should send a "text" message to the correct destination (the one that was supplied on the command line).
    6. All incoming and outgoing messages should be displayed in the text window of your IM client.
    Test your code by sending text messages to server:echo. This will simply echo the messages back to you, and will let you verify that the communication is happening properly.
  5. Make sure that your code works by sending messages to server:will, another personality of the server.
  6. Modify your code to take the following command-line arguments:
    -u username     Specify the user name
    -d destination     Specify the destination
    -h     Print usage information
    The -u argument is optional (for the user, not for the programmer). If it is missing, you should use the username of the person running the code. All text messages should be sent to the specified destination. All control messages (hello and goodbye) should be sent to server as before.
  7. Start a server, and two clients, and verify that you can send messages from one to the other. Quit one of the clients and start it again. Make sure that everything still works.
  8. Add a button that pops up a new window that allows the user to select a new message destination.
  9. Add a checkbox that enables an "away message" feature. The should automatically reply to any text messages received when the feature is enabled. If the sender of the message also has an away feature enabled, this could result in an infinite loop. You should design your code to avoid this infinite loop.
  10. Extra credit: Make your GUI modal, so that it's impossible to enter a text message when you're not allowed to send one.
  11. Extra credit: Add a status bar to your GUI that tells the user what the code is doing (connecting, waiting for reply, etc).
  12. Extra credit: Make the away message be user-configurable, either through a Qt dialog, or through a configuration file, or (even better) both. Document this feature in your README file.
  13. Extra credit: Modify your interface to allow you to conduct multiple sessions at the same time. Use a tabbed display window, with one tab for each person you're talking to. As messages come in from new clients, open a new tab. Include the ability to close tabs (perhaps with a key combination like ctrl-w).
  14. Extra credit: Add the ability to make conference calls. The main part of this is being able to send the same message to more than one person. You should also add a mechanism for specifying who is in the conference call, and for dealing with people who leave it early.
  15. Extra credit: Think of a cool feature for the IM client and implement it. To count, the feature should be substantially different from the other features you've already implemented. If you want to run an idea by us, email us and tell us about it.

Grading

Most of the points in this lab will be for having the code work as described above. We will deduct points for the following things:
  1. Not compiling. If your code does not compile, then you will get no points for this lab. We've been lenient on this in the past, but we will enforce the rule strictly from now on.
  2. Warnings or errors in the compile. Your code should not generate any warning messages when compiled with the -Wall flag.
  3. Deviations from the coding guidelines.
  4. Incorrect or poorly-written algorithms.

What to Hand In

You should hand in all of your code, your README, your Makefile, and your Doxyfile. As with the previous lab, make sure you list all of your object files in your Makefile, or use qmake. Describe your build procedure in your README file. You should make a tarball of your code and other files, and submit it through our web-based submission system.

Thoughts

  1. We're not going to use a lot of the functionality of the networking classes for the lab. If you're not already familiar with socket communications, then think of them like this: The client opens a connection to the server, over which data can flow in either direction. Writing to this connection from the client causes the data to appear at the server, and vice versa. When data is ready to be read, the socket classes emit a signal, which connects with a slot in the receiving code. There's also signals for connections being established and closed. We'll talk about sockets a little in class, so come armed with questions.
  2. Take the time to look at the client code, and work out what it's doing. This will make your job easier when you come to integrate it with your own code. It's probably also a good idea to look up some of the Qt networking classes, so that you know what they can do.
  3. Take some time and think about the design of your code before you start. This will really, really help you in the long run. There are several cases where you're waiting for an asynchronous reply before you can proceed to the next step, but you don't want the interface to freeze in the meantime. A common way around this is to keep some variables somewhere that tell you if it's OK to send messages, enter text, etc. You can change the state of these variables as the replies come in, and check them when you want to send messages out.
Page written by Bill Smart.