Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

What to do You are supposed to design and implement a chat server and client - in Java (and only in Java, as all assignments

What to do

You are supposed to design and implement a chat server and client - in Java (and only in Java, as all assignments that follow this one). The server serves as a "central hub", which allows chat clients to:

Register for participating in the chat (aka JOIN)

Leave the chat (aka LEAVE)

Send messages (called "notes") to all registered chat participants.

Similarly, the chat client will be able to:

JOIN a chat, i.e., register with a known chat server to participate in the chat. The information of the server, i.e., its IP/port, needs to be read from a properties file upon starting up the chat client. Note that a client who has joined before, should not be able to join again.

LEAVE a chat - while not terminating itself, i.e. it may register again at some later time. Note that leaving a chat anticipates that the client has joined the chat before.

Send a note to all other chat clients, using the chat server. Note that a client can only send a note, if it has joined the chat before. For simplicity's sake we want to assume that a message is being forwarded by the server to ALL chat participants, including the originator of the note.

SHUTDOWN, which terminates the chat client. This may involve to first leave the chat, if the client is registered at the server.

SHUYTDOWN_ALL, which shuts down the whole chat, including the server.

In order to trigger all above activities/states, the client needs to provide a primitive command-line user interface for the user to use. The interface will recognise the following "commands":

JOIN IP port

LEAVE

SHUTDOWN

SHUTDOWN_ALL

any other text, which is interpreted to be a note to be sent to all other registered chat clients. Note, however, that the client has to be a chat participant, before being able to send notes.

Clients have logical, human-readable names, like Paul, Mickey Mouse, Sandy etc. When sending a message, the logical name will be prepended to the message that is supposed to be sent and thus will automatically be displayed on the receiving side, when displaying the message string.

Hints

It is very important to make INTENSE use of the OOP power of Java - for efficiency's sake as well as your own sanity.

You will want to make the communication between client and server, i.e., the "network protocol", as efficient as possible, from a design perspective. That is why I ask you to design and implement a class Message. Messages are what you send over the network via object streams. Hence, class Message has to implement the interface java.io.Serializable.

A message has a type and content. There are getter and setter methods and a constructor that takes a message's type and content as arguments - content has to be general enough to accommodate any type of data for a message to carry and for that reason needs to be of type Object.

Message types are defined in an interface called MessageTypes. Each type is realized as a symbolic constant of type int and corresponds to JOIN, LEAVE, NOTE and the two shutdown actions, see above. Understand that each message type suggests a certain type of content, i.e. JOIN and LEAVE will correspond with connectivity information of the chat client, while NOTE corresponds with String.

I said above that messages are sent over object streams. As you know, there are InputStreams and OutputStreams. You have learned in CS460/560 how to get your hands on those streams, once you have a Socket object. If you work with object streams, all you need to do is to wrap those primitive streams with ObjectInputStream() and ObjectOutputStream() constructors. Once you have those object streams, you can call readObject() and writeObject() upon them. And that is how you send Messages.

There is a caveat, however. You need to be careful with the instantiation of object stream objects, i.e., the order of the instantiation matters. An ObjectInputStream initiated on one side of a network connection needs to match with the instantiation of a corresponding ObjectOutputStream on the other side and vice versa. If you, let's say, instantiate first the ObjectInputStreams on both sides, and then the ObjectOutputStreams on both sides thereafter, you will get weird effects and errors. In summary, the instantiations need to "cross over".

I also ask you to create a class NodeInfo that contains the tuple "IP/port/logical name" of a chat client, making it convenient to send an object of that type in the content field of a message. This is needed e.g. in JOIN and LEAVE messages. Make sure to also have this class implement interface java.io.Serializable as it is going to be sent over the object streams and thus needs to be serializable, just like Message objects.

One last word about java.io.Serializable: this is what is called a "marker interface". A marker interface doesn't require you to actually implement anything. It is just a way of telling the runtime system "Hey, I intend to send objects of this type over the network, please deal with it and serialize the objects for me".

To get you started quickly, I will provide some of the classes described above:

Message.java

MessageTypes.java

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Students also viewed these Databases questions