gvsu/cs656/lab4/ChatClient.java
josh 78dfaf2a8e removed tabs
git-svn-id: svn://anubis/gvsu@273 45c1a28c-8058-47b2-ae61-ca45b979098e
2008-11-25 21:52:57 +00:00

357 lines
11 KiB
Java

/* Josh Holtrop
* 2008-12-04
* CS656
* Lab 4
*/
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.io.*;
import java.util.*;
import java.net.*;
import edu.gvsu.cis.cs656.lab4.server.PresenceService;
import edu.gvsu.cis.cs656.lab4.server.RegistrationInfo;
public class ChatClient
{
private PresenceService myPServ;
private String myUserName;
private Thread myListenThread;
private ChatClientListener myListener;
private RegistrationInfo myRegistrationInfo;
/**
* This class provides a thread to listen for incoming connections.
*/
private class ChatClientListener implements Runnable
{
ServerSocket mySocket;
public ChatClientListener()
{
try
{
/* Just listen on any available TCP port */
mySocket = new ServerSocket(0);
}
catch (Exception e)
{
System.err.println("Error creating listener thread!");
e.printStackTrace();
System.exit(-1);
}
}
public int getPort()
{
return mySocket.getLocalPort();
}
public String getHost()
{
return mySocket.getInetAddress().getHostName();
}
/* called when the thread is first scheduled */
public void run()
{
Socket s;
/* wait indefinitely for new connections */
for (;;)
{
try
{
s = mySocket.accept();
Thread cclt = new Thread(new ChatClientListenerThread(s));
cclt.start();
}
catch (Exception e)
{
}
}
}
/**
* This class provides a listener for any connections that come in.
* All it does is print any received chat messages from the remote
* user to this user's screen.
*/
public class ChatClientListenerThread implements Runnable
{
Socket mySocket;
public ChatClientListenerThread(Socket s)
{
mySocket = s;
}
public void run()
{
try
{
InputStream is = mySocket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while (!mySocket.isClosed())
{
/* read and print a message from a peer */
String in = br.readLine();
if (in == null)
break;
System.out.println(in);
System.out.print("> ");
}
}
catch (Exception e)
{
return;
}
}
}
}
/* construct the main ChatClient object */
public ChatClient(PresenceService pserv, String userName)
{
myPServ = pserv;
myUserName = userName;
}
public void run()
{
try
{
myListener = new ChatClientListener();
myRegistrationInfo =
new RegistrationInfo(myUserName,
InetAddress.getLocalHost().getHostName(),
myListener.getPort(),
true);
if (!register())
{
return;
}
}
catch (Exception e)
{
e.printStackTrace();
return;
}
/* Start a thread to listen for connections in */
myListenThread = new Thread(myListener);
myListenThread.start();
mainloop();
}
/* call the register function in the presence service */
private boolean register()
{
try {
myPServ.register(myRegistrationInfo);
} catch (Exception e) {
System.out.println("Exception caught when registering!");
e.printStackTrace();
return false;
}
return true;
}
/* call the unregister function in the presence service */
private boolean unregister()
{
try {
myPServ.unregister(myUserName);
} catch (Exception e) {
System.out.println("Exception caught when unregistering!");
e.printStackTrace();
return false;
}
return true;
}
/* this is the main wait-for-input-and-respond loop */
private void mainloop()
{
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
String line;
try
{
for (;;)
{
/* print a prompt */
System.out.print("> ");
/* read a line of input */
line = br.readLine();
if (line == null)
break;
line = line.trim();
if (line.equals(""))
continue;
/* break the input into the command word, and the rest */
String command, rest;
int spaceIndex = line.indexOf(' ');
if (spaceIndex > 0)
{
command = line.substring(0, spaceIndex);
rest = line.substring(spaceIndex + 1);
rest = rest.trim();
}
else
{
command = line;
rest = "";
}
if (command.equals("help") || command.equals("?"))
{
System.out.println("Commands:");
System.out.println(" friends - view a list of all peers on the system");
System.out.println(" talk {username} {message} - send message to username");
System.out.println(" broadcast {message} - send message to every available user");
System.out.println(" busy - set status to busy/away");
System.out.println(" available - set status to busy/away");
System.out.println(" exit - disconnect and exit program");
}
else if (command.equals("talk"))
{
String user = "";
int idx;
if ((idx = rest.indexOf(' ')) > 0)
{
user = rest.substring(0, idx);
RegistrationInfo ri = myPServ.lookup(user);
if (ri == null)
{
System.err.println("Could not find user \"" + user + "\"!");
}
else
{
/* only send a message to available users */
if (ri.getStatus())
{
String message = rest.substring(idx + 1);
sendUserMessage(user, message);
}
else
{
System.out.println(user + " is busy!");
}
}
}
else
{
System.out.println("Syntax: talk {user} {message}");
}
}
else if (command.equals("busy"))
{
if (myRegistrationInfo.getStatus())
{
myRegistrationInfo = new RegistrationInfo(
myRegistrationInfo.getUserName(),
myRegistrationInfo.getHost(),
myRegistrationInfo.getPort(),
false
);
unregister();
register();
System.out.println("Status set to busy");
}
}
else if (command.equals("available"))
{
if (!myRegistrationInfo.getStatus())
{
myRegistrationInfo = new RegistrationInfo(
myRegistrationInfo.getUserName(),
myRegistrationInfo.getHost(),
myRegistrationInfo.getPort(),
true
);
unregister();
register();
System.out.println("Status set to available");
}
}
else if (command.equals("exit"))
{
myListenThread.interrupt();
break;
}
else
{
System.out.println("Unrecognized Command! Type 'help' or '?' for help!");
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
unregister();
System.exit(0);
}
/* a useful subroutine to break out the task of sending a
* message to a particular user */
private void sendUserMessage(String user, String message)
{
try
{
RegistrationInfo ri = myPServ.lookup(user);
if (ri != null)
{
Socket s = new Socket(InetAddress.getByName(ri.getHost()),
ri.getPort());
OutputStream os = s.getOutputStream();
message = myUserName + ": " + message;
os.write(message.getBytes());
s.close();
}
}
catch (Exception e)
{
System.err.println("Error sending message");
e.printStackTrace();
}
}
public static void main(String[] args)
{
String user = "user";
String host = "localhost";
for (int arg = 0; arg < args.length; arg++)
{
switch (arg)
{
case 0:
user = args[arg].replace(' ', '_');
break;
case 1:
host = args[arg];
break;
default:
usage();
}
}
PresenceService pServ = new PresenceServiceImpl();
ChatClient chatClient = new ChatClient(pServ, user);
chatClient.run();
}
private static void usage()
{
System.err.println("Usage: java ChatClient [-master] {user} {host}");
System.exit(42);
}
}