User to User Chats
In this part you will be enhancing your client to allow for communication between other clients. In order to separate individual user to user chats, you will need to implement a chat executable program which your client will execute as child processes. Using the xterm program in tandem with this chat executable you’ll be able to create a client that spawns new windows as needed to display chats. The behavior will emulate what you may be familiar with on facebook or google hangouts functionality in terms of automatically spawning new small windows dedicated for chatting as opposed to monopolizing the user’s entire view of the screen.
When a client wants to begin a chat session with another user, they type into the client window on stdin the client command /chat. This will trigger the client to send to the server a new verb, MSG. The MSG verb will be used for communication of ALL chat messages between the server and client. Let’s consider an example:
- Paul initiates chat using the /chat command, the message is formatted into the MSG\r\n\r\n protocol and sent to the server.
When the server receives the MSG verb, it sends the same message back to both the To and FROM user. - When Paul’s and Neal’s client receive the MSG\r\n\r\n back from the server, the client program will create a UNIX Domain Socket to share with the child process (for the pop-up chat window) to communicate over, then fork and execv an xterm terminal which will run your ./chat program.
- The chat program is a simple program which takes input from stdin and sends to the Client program, prints on stdout messages from the client program, and handles the command /close which terminates the child process (same as closing the terminal window).
This is the initial creation of all user to user chats. Once both users have an xterm chat window open for communication, the users can freely type messages to each other. Incoming messages should be proceeded by the > symbol and outgoing messages by < in the chat window. With each message entered in the xterm on stdin, the chat program should relay the information to the client through their Unix Domain socket. The client then converts the message into the Wolfie Protocol MSG verb and sends to the server. The below figure illustrates the steps.
A user can close a chat window at anytime using either the close button on the xterm window or by using the command /close. When the window is closed on one client it has no impact on the client who was chatting with the user. In the figure below Paul closed the chat window but Neal still has it open. When Neal types a message to Paul it is sent to the server (Step 1). The sewer will forward the message back to Paul & Neal (Step 2). Since Paul has no existing window, his client creates a new window and displays the message. Neal’s client will just display the message since the xterm is already open.
Paul closed the chat window and then wants to send Neal a new message. To initiate the chat again, he would need to type /chat command in his client. This will send the MSG verb to the sewer (Step 1 in figure below). Upon the server’s response, Paul’s client would spawn a new chat window. Neal and Paul’s chat windows will then both display the
Overall, the protocol MSG verb is generic. The server has no knowledge of the chat windows open or closed. It is the client program’s responsibility to open, close, and manage the chat windows. In this way, it doesn’t matter if the xterm window is closed because every time MSG is received the client will check to see if a window already exists for communicating with theuser and if not it will fork and exec a new xterm process to become the window needed for communication. If the window does exist then the message is passed through the Unix domain socket and displayed appropriately on the chat window.
If one of the user’s disconnects from the server or does not exist, but a message is sent to this user, the server will respond with an ERR message.
Added Client command
/chat
The /chat command requires the name of the user to send the message to and the message to be sent. The client program will send to the server the MSG verb to communicate the message to the other user.
/logout
Update the functionality of the command to now additionally close all the chat windows and all file descriptors prior to exiting the client program.
Chat Program
Usage:1
2./chat UNIX_SOCKET_FD
UNIX_SOCKET_FD The Unix Domain File Descriptor number.
When the server sends MSG verb to your client it should fork and exec xterm, which in turn will exec your chat program in a basic terminal. This will act as the interface to communicate with another user much like chats on Facebook or hangouts work. These will act as the small popups to chat in while the client remains the manager for the connection with the server. The chat program will use Unix domain sockets to communicate with the parent client process. Using socketpair() you can declare two anonymous sockets and pass the file descriptor to the chat program as an argument. You can also declare the sockets as you would normally using socket(). In either case you must use AF_UNIX as the domain.
xterm is a powerful terminal emulator as it allows for a lot of customization using command line arguments. You should study the man page for xterm to see what arguments will help make your program as easy to use as possible. To get you started, the format to fork and exec the ./chatprogram in xterm is as follows:
Example execution string: “xterm -geometry 45x35+%d -T %s -e ./chat. %d”
Each of the arguments have the following meaning.
-geometry geometry: This argument allows you to set the size and location of the xterm window opened. Geometry format is described here under “geometry specifications”. However, all you really need to know is that is takes the format WIDTHxHEIGHT+XOFF+YOFF where width and height are in characters and XOFF and YOFF is in pixels. In the suggested execution string above you can see that you can omit the YOFF value and you can use sprintf to set the XOFF so the windows spawned are not stacked on one another.
-T string: With this flag you can set the title of the string to the username being communicated with so the user has a quick reference of which window is chatting with whom. Use %s format specifier to insert the username for the chat.
-e program [arguments … ]: finally there is the most important flag. -e specifies the executable to be run when the terminal opens. The arguments to the program follow immediately after as you would type them in the terminal. The execution string shows how you would pass the unix domain socket file descriptor. Use %s format specifier for the file descriptor of the Unix domain socket.
The chat program should prompt the user for input, anything the user types in followed by pressing the enter-key should be considered a message with the exception of the /close command. The /close command simply closes the window and the Unix domain socket in the parent. There is no protocol messages that need to be exchanged with the server when this command is used. The Client forwards each MSG received to the corresponding chat window via each open chat’s Unix domain socket.
The protocol has new verbs that must be implemented to support these user features. As we have seen in the figures, the MSG verb will deliver the information of who the message is to, whom it is from, and the message being sent. Additionally, add a new verb, UOFF, which will be used to notify ALL clients connected to the server of a user logging out or disconnecting from the server.
Client crash or error termlnatlon
Crashes happen so the UOFF verb should handle both the case of a client disconnecting and of a client logging off. If someone’s chatting partner disconnects and the chat window is still open for that user, when the UOFF verb is received, the chat window should print a message that informs the user of the disconnection. The xterm window should then close on any key press. This is to prevent the user from attempting to send anything to a disconnected user. Think about how the server can handle errors when trying to pass along user messages, and accordingly turn that error into a UOFF broadcast verb to notify all clients of the user’s disconnection.
Server
On the server side the communication threads must handle receiving and sending messages to the proper clients using the MSGprotocol defined in the prior figures. The server also must handle forwarding the UOFF verb to all still connected clients when a user disconnects or logs off the server.