如果不通过服务器,我无法让客户端向另一个客户端发送消息。这是一个强制性的学校项目,应该这样实施。如果有人可以帮助我,我将不胜感激。
服务器接口:
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
public interface ChatServerInt extends Remote {
public abstract void register(ChatClientInt inClient) throws RemoteException;
public abstract ChatClientInt[] getClients() throws RemoteException;
public void disconnect(ChatClientInt client) throws RemoteException;
}
服务器实现:
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class ChatServerImp extends UnicastRemoteObject implements ChatServerInt, Runnable {
private ChatClientInt[] clientList;
int counter = 0;
private ArrayList<String> connectedClients;
/**
* List of all registered remote clients.
*/
private List<ChatClientInt> clients = null;
/**
* Construct an instance of the chat server.
*/
public ChatServerImp() throws RemoteException {
// initialise the list of client objects.
clients = new ArrayList<ChatClientInt>();
connectedClients = new ArrayList<String>();
clientList = new ChatClientInt[16];
}
/**
* Register a chat client.
*/
public void register(ChatClientInt inClient) throws RemoteException {
// perform registration.
synchronized(clients)
{
clients.add(inClient);
clientList[counter++] = inClient;
inClient = new ChatClientImp();
for(int i = 0 ; i < clients.size();i++) {
System.out.println(inClient.getName()+ "has joined\n");
}
}
}
/**After registering, each client will request the list of connected users.
* Get a list of chat clients.
*/
public synchronized ChatClientInt[] getClients() throws RemoteException {
// generate and return the list
return clientList;
}
public void disconnect(ChatClientInt client) throws RemoteException {
for(int i = 0; i < clients.size(); i++) {
System.out.println(client.getName() + "" + "has joined \n");
}
clients.remove(client);
}
/**
* Generate a random subset. Based on an implementation of D. Knuth's
* @return
*/
private static <T> List<T> randomSample2(List<T> items, int m) {
Random rnd = new Random();
for(int i=0;i<items.size();i++){
int pos = i + rnd.nextInt(items.size() - i);
T tmp = items.get(pos);
items.set(pos, items.get(i));
items.set(i, tmp);
}
return items.subList(0, m);
}
/**
* Run the server's main thread. The server should periodically
* iterate through all registered clients to find out if they
* are still alive. Any dead clients will be removed from the
* client list.
*/
public void run() {
while(true) {
//System.out.println("waiting for client connection....\n");
// sleep for a while
try {
Thread.sleep(5000);
// iterate through all the clients we know. if we can't communicate with the client
// then eliminate it else if we can communicate with the client then do nothing.
for(int i =0; i < clients.size(); i++) {
try {
if(clients.get(i).getName()==null) {
clients.remove(clients.get(i).getName());
System.out.println("Disconnected clients:\n" + clients.get(i).getName());
}
}
catch (RemoteException e) {e.printStackTrace();}
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* Start the chat server.
* @param args
*/
public static void main(String[] args) throws Exception {
//ChatServerInt server;
try {
String serverName = "rmi://localhost/ChatServer";
// create an instance of the chat server
//server = (ChatServerImp) new ChatServerImp();
//Launch the registry - saves invoking it manually
java.rmi.registry.LocateRegistry.createRegistry(1099);
// register the instance with the RMIRegistry
Naming.rebind(serverName, new ChatServerImp());
//Naming.rebind(serverName, server);
// create the server thread and start it
//Thread t = new Thread(server).start();
System.out.println("Server running.....\n");
}
catch(RemoteException ex) {
System.out.println("Error binding the server to rmi");
}
}
}
消息接口:
import java.util.HashSet;
public interface MessageInt {
/**
* Add a chat recipient to the list of receivers
* @param inClient
*/
public abstract void addRecipient(ChatClientInt inClient);
/**
* Get the set of clients that have seen this message
* @return
*/
public abstract HashSet<ChatClientInt> getRecipients();
/**
* Get the message content.
* @return
*/
public abstract String getContent();
/**
* Get an ID for a sender of the message
* @return
*/
public abstract String getSource();
}
消息实现:
import java.io.Serializable;
import java.util.HashSet;
public class MessageImp implements MessageInt, Serializable {
/**
*
*/
private static final long serialVersionUID = -2686034785384409672L;
HashSet<ChatClientInt> clientSet = new HashSet<ChatClientInt>();
String messageContent;
String messageSource;
public MessageImp(String inUser , String inMsg) {
messageSource = inUser;
messageContent = inMsg;
}
/**
* Add a chat recipient to the list of receivers
* @param inClient
*/
public void addRecipient(ChatClientInt inClient) {
synchronized(inClient) {
clientSet.add(inClient);
}
}
/**
* Get the set of clients that have seen this message
* @return
*/
public HashSet<ChatClientInt> getRecipients() {
return clientSet;
}
/**
* Get the message content.
* @return
*/
public String getContent() {
return messageContent;
}
/**
* Get an ID for a sender of the message
* @return
*/
public String getSource() {
return messageSource;
}
}
客户端接口:
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface ChatClientInt extends Remote {
/**
* Process a newly received message.
*
* @param inMessage
*/
public void processMessage(MessageInt inMessage)throws RemoteException;
/**
* Returns the name of the client.
*/
public String getName() throws RemoteException;
public boolean sendMessage(MessageInt inMessage) throws RemoteException;
}
客户端实现:
import java.io.Serializable;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;
public class ChatClientImp extends UnicastRemoteObject implements ChatClientInt, Runnable {
/**
*
*/
private static final long serialVersionUID = 74130345076834009L;
private ArrayList <String> eventHistory = new ArrayList<String>();
private HashSet<ChatClientInt> clientSet = new HashSet<ChatClientInt>();
private List<ChatClientInt> clients;// = new ArrayList<ChatClientInt>();
ChatClientInt[] listFromServer = new ChatClientInt[4];
String clientName;
String strMessage;
MessageInt messageObj;
ChatServerInt serverObj;
public ChatClientImp() throws RemoteException {
super();
clients = new ArrayList<ChatClientInt>();
}
public void processMessage(MessageInt inMessage) throws RemoteException {
System.out.println("message:" + inMessage.getRecipients().toString() + inMessage.getSource() + inMessage.getContent() + "\n");
}
public String getName() throws RemoteException {
return clientName;
}
public synchronized boolean sendMessage(MessageInt inMessage) throws RemoteException {
boolean success = false;
for(int i = 0; i < clients.size(); i++) {
clients.get(i).processMessage(inMessage);
inMessage.addRecipient(clients.get(i));
success = true;
}
return success;
}
public void displayMessage(String displayName, String displayMsg) {
Iterator<ChatClientInt> it = clientSet.iterator();
while(it.hasNext()) {
System.out.println(displayName + displayMsg + "\n");
}
}
public void run() {
Scanner scanner = new Scanner(System.in);
String userName = "";
try {
this.serverObj =(ChatServerInt) new ChatServerImp();
} catch (RemoteException e) {
e.printStackTrace();
}
// Keep requesting until a name is submitted that is not already used.
// checking for the existence of a name and adding the name
// is done while locking the set of names.
System.out.println("Please Enter a username\n");
while(true) {
userName = scanner.nextLine();
if(userName==null) {
return;
}
clientName = userName;
try {
serverObj.register(ChatClientImp.this);
listFromServer = serverObj.getClients();
clientSet.add(this);
} catch (RemoteException e) {
e.printStackTrace();
}
System.out.println("Hi" + " " + clientName + " " + "enter your message\n");
String msg = scanner.nextLine();
if(msg.equals("exit")) {
try {
serverObj.disconnect(this);
System.exit(0);
}
catch (RemoteException e) {
e.printStackTrace();
}
}//end if
if((listFromServer.length) > 1) {
System.out.println("list from client is" + " " + listFromServer.length + "going to try to send message.....\n");
try {
this.messageObj = new MessageImp(userName, msg);
boolean result = this.sendMessage(messageObj);
if(result) {
System.out.print("sending result is:" + result + "\n");
} else {
System.out.println("sending was not successful\n");
}
} catch (RemoteException e1) {
System.out.println("Error tryiing to send message from the Run()\n");
}
} else {
System.out.println("There is no one else logged on\n");
}
}
}
public static void main(String[] args) throws RemoteException {
String serverUrl= "rmi://localhost/ChatServer";
try {
ChatServerInt server = (ChatServerInt)Naming.lookup(serverUrl);
Thread thread = new Thread(new ChatClientImp());
thread.start();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
}