一个用rmi实现简单的双向消息发送的聊天程序,客户机可以向服务器注册自己. 此代码原自developing java enterprise app一书(自己写不了, ),本机调试通过.
一:远程接口 接口1: package message; import java.rmi.Remote; import java.rmi.RemoteException; /** * coder: taie */ public interface MessageReceiver extends Remote{ void print(String s) throws RemoteException; }
接口2: package message; import java.rmi.Remote; import java.rmi.RemoteException; /** * coder: taie */ public interface MessageServer extends Remote { static String SERVER_NAME = "Message_Server"; static int FAILURE=-1; static int success=0; void send(String name, String message) throws RemoteException; int register(String name,MessageReceiver m)throws RemoteException; } javac 编译以上接口.
二:服务器端,server类 package server; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject; import java.util.Enumeration; import java.util.Hashtable;
import message.MessageReceiver; import message.MessageServer; /** * coder: taie */ public class Server extends UnicastRemoteObject implements MessageServer{ // a hashtable 存储用户 static Hashtable receivers=new Hashtable(5); public Server()throws RemoteException{ super(); } public void send(String name,String message)throws RemoteException{ for(Enumeration e=receivers.elements();e.hasMoreElements();) {MessageReceiver m=(MessageReceiver)e.nextElement(); m.print(name+":"+message); } } public int register(String name,MessageReceiver m){ int retval=MessageServer.FAILURE; // 空注册检测 if((name!=null)&&(m!=null)){ //唯一用户名 if(receivers.get(name)==null) { receivers.put(name,m); System.out.println("added "+name); retval=MessageServer.success; }else{ System.out.println("Could not add client because"+name +"already exists on server."); } } return retval; } public static void main(String[] args){ // System.setSecurityManager(new RMISecurityManager()); try{ //create an instance MessageServer srv=new Server(); //server类创建注册表 Registry reg=LocateRegistry.createRegistry( Registry.REGISTRY_PORT); reg.rebind(MessageServer.SERVER_NAME,srv); System.out.println("Server bound and Started!"); }catch(Exception e){ System.err.println("Server exception:"+e.getMessage()); e.printStackTrace(); } } } rmic server.Server server类创建了自己的注册表,不需要运行rmiregistry 三:客户端,client,主要是界面编码 package client; import java.awt.BorderLayout; import java.awt.Frame; import java.awt.TextArea; import java.awt.TextField; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; import message.MessageReceiver; import message.MessageServer; /** * coder: taie */ public class Client extends Frame implements MessageReceiver, ActionListener{ TextField tf; TextArea ta; static String name; static MessageServer server; public Client()throws RemoteException{ setTitle(name); setLayout(new BorderLayout()); tf=new TextField(30); tf.addActionListener(this); add("South",tf); ta=new TextArea(20,20); add("Center",ta); addWindowListener(new WindowCloser()); UnicastRemoteObject.exportObject(this); } public void actionPerformed(ActionEvent e){ try{ server.send(name,tf.getText()); }catch(Exception ea){ System.out.println("Client exception "+ea.getMessage()); ea.printStackTrace(); } tf.setText(""); tf.selectAll(); } public void print(String s){ ta.append(s+"\n"); } public static void main(String[] args){ if(args.length<1){ System.out.println("usage:java client.client ClientName."); System.exit(-1); } name=args[0]; try{ Client cf=new Client(); cf.pack(); cf.show(); server=(MessageServer)Naming.lookup( MessageServer.SERVER_NAME); int s=server.register(args[0],cf); if(s==MessageServer.FAILURE)throw new Exception( "could not connect to server."); }catch(Exception e){ System.err.println("Client exception: "+e.getMessage()); e.printStackTrace(); System.exit(-1); } } }
class WindowCloser extends WindowAdapter{ public void windowClosing(WindowEvent e){ System.exit(-1); } } rmic client.Client 编译客户端
各项编译通过后,首先java server.Server启动服务器端, 再执行客户端(5个以内,这里开启2个)java client.Client test1;java client.Client test2 2个客户端正常通信,本机调试通过. 
|