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
- 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.
- Modify your
Message classes to include a
destination tag, which specifies where the message
should be sent.
- 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.
- Integrate the networking code with the IM client GUI that you
created in a previous lab. The executable should have the
following features:
- 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.
- 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.
- 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.
- 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.
- Typing in text should send a "text" message to the
correct destination (the one that was supplied on the command
line).
- 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.
- Make sure that your code works by sending messages to
server:will, another personality of the server.
- 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.
- 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.
- Add a button that pops up a new window that allows the user to
select a new message destination.
- 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.
- Extra credit: Make your GUI modal, so that it's impossible
to enter a text message when you're not allowed to send one.
- Extra credit: Add a status bar to your GUI that tells the
user what the code is doing (connecting, waiting for reply, etc).
- 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.
- 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).
- 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.
- 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:
- 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.
- Warnings or errors in the compile. Your code should not generate
any warning messages when compiled with the
-Wall
flag.
- Deviations from the coding guidelines.
- 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
- 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.
- 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.
- 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.