import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.util.*; import java.io.*; import java.net.*; public class ChatClient { private PresenceService myPServ; private String myUserName; private Thread myListenThread; private ChatClientListener myListener; private RegistrationInfo myRegistrationInfo; private class ChatClientListener implements Runnable { ServerSocket mySocket; public ChatClientListener() { try { 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(); } public void run() { Socket s; for (;;) { try { s = mySocket.accept(); Thread cclt = new Thread(new ChatClientListenerThread(s)); cclt.start(); } catch (Exception e) { } } } 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(); System.out.println(in); } } catch (Exception e) { return; } } } } public ChatClient(PresenceService pserv, String userName) { myPServ = pserv; myUserName = userName; } public void run() { myListener = new ChatClientListener(); myRegistrationInfo = new RegistrationInfo(myUserName, myListener.getHost(), myListener.getPort(), true); if (!register()) { return; } /* Start a thread to listen for connections in */ myListenThread = new Thread(myListener); myListenThread.start(); mainloop(); } private boolean register() { try { myPServ.register(myRegistrationInfo); } catch (Exception e) { System.out.println("Exception caught when registering!"); e.printStackTrace(); return false; } return true; } private boolean unregister() { try { myPServ.unregister(myUserName); } catch (Exception e) { System.out.println("Exception caught when unregistering!"); e.printStackTrace(); return false; } return true; } private void mainloop() { BufferedReader br = new BufferedReader( new InputStreamReader(System.in)); String line; try { for (;;) { System.out.print("> "); line = br.readLine(); if (line == null) break; line = line.trim(); if (line.equals("")) continue; 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("friends")) { RegistrationInfo[] friends = myPServ.listRegisteredUsers(); System.out.println("Registered Users:"); for (RegistrationInfo ri : friends) { System.out.print(ri.getUserName()); System.out.print(" ["); System.out.print(ri.getStatus() ? "available" : "busy"); System.out.println("]"); } } else if (command.equals("talk")) { String user = ""; int idx; if ((idx = rest.indexOf(' ')) > 0) { user = rest.substring(0, idx); RegistrationInfo ri = myPServ.lookup(user); String message = rest.substring(idx + 1); sendUserMessage(user, message); } else { System.out.println("Syntax: talk {user} {message}"); } } else if (command.equals("broadcast")) { RegistrationInfo[] ris = myPServ.listRegisteredUsers(); for (RegistrationInfo ri : ris) { if (!ri.getUserName().equals(myUserName)) { sendUserMessage(ri.getUserName(), rest); } } } else if (command.equals("busy")) { if (myRegistrationInfo.getStatus()) { myRegistrationInfo = new RegistrationInfo( myRegistrationInfo.getUserName(), myRegistrationInfo.getHost(), myRegistrationInfo.getPort(), false ); unregister(); register(); } } else if (command.equals("available")) { if (!myRegistrationInfo.getStatus()) { myRegistrationInfo = new RegistrationInfo( myRegistrationInfo.getUserName(), myRegistrationInfo.getHost(), myRegistrationInfo.getPort(), true ); unregister(); register(); } } else if (command.equals("exit")) { unregister(); myListenThread.interrupt(); break; } else { System.out.println("Unrecognized Command! Type 'help' or '?' for help!"); } } } catch (Exception e) { e.printStackTrace(); } System.exit(0); } 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; String host = "localhost"; int port = 1099; if (args.length < 1) { System.err.println("Usage: ChatClient [host[:port]]"); return; } user = args[0]; user = user.replace(' ', '_'); if (args.length >= 2) { StringTokenizer st = new StringTokenizer(args[1], ":"); if (st.hasMoreTokens()) { host = st.nextToken(); if (st.hasMoreTokens()) { port = Integer.parseInt(st.nextToken()); } } } if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); } try { Registry registry = LocateRegistry.getRegistry(host, port); PresenceService pserv = (PresenceService) registry.lookup("PresenceService"); if (pserv == null) { System.err.println("Error: Could not connect to presence service"); return; } ChatClient cc = new ChatClient(pserv, user); cc.run(); } catch (Exception e) { System.err.println("ChatClient exception:"); e.printStackTrace(); } } }