358 lines
11 KiB
Java
358 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";
|
|
int port = 42842;
|
|
|
|
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(host, port);
|
|
|
|
ChatClient chatClient = new ChatClient(pServ, user);
|
|
chatClient.run();
|
|
}
|
|
|
|
private static void usage()
|
|
{
|
|
System.err.println("Usage: java ChatClient [-master] {user} {host}");
|
|
System.exit(42);
|
|
}
|
|
}
|