我一直在绞尽脑汁试图找出问题所在,我很确定服务器连接建立得很整齐。我什至放了一些系统打印以确保发送和接收对象。让我先发布我的代码。
RemoteService.java(接口):
package testrmi;
import java.rmi.*;
import javax.swing.JPanel;
public interface RemoteService extends Remote {
public Object[] getServiceList() throws RemoteException;
public Service getService(Object SvcKey) throws RemoteException;
}
服务器提供的服务使用的Service.java(接口):
package testrmi;
import javax.swing.*;
import java.io.*;
import java.rmi.Remote;
public interface Service extends Serializable {
public JPanel getGuiPanel();
}
RSimpl.java(RemoteService 接口实现者)
package testrmi;
import java.rmi.*;
import java.rmi.server.*;
import java.util.*;
public class RSimpl implements RemoteService {
HashMap<String, Service> map;
public RSimpl() throws RemoteException
{
//super();
setUpServices();
}
public void setUpServices()
{
map = new HashMap<String, Service>();
map.put("Dice Roll Service", new DiceRoll());
map.put("Calculator Service", new Calculator());
map.put("Clock Service", new DigitalClock1());
// Keep Adding Services On The Go!
}
public Object[] getServiceList()
{
return map.keySet().toArray();
}
public Service getService(Object SvcKey)
{
System.out.println(SvcKey + " request has been recieved");
Service theService = map.get(SvcKey);
return theService;
}
}
Client.java(客户端,这看起来很脏:p)
package testrmi;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
JFrame frame;
JPanel mainPanel;
JComboBox<Object> comboBox;
RemoteService server;
int i = 0;
Object[] error = {"Cannot Load Services"};
public void buildGUI()
{
frame = new JFrame("Service Browser");
mainPanel = new JPanel();
attemptConnect();
frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
frame.getContentPane().add(BorderLayout.NORTH, comboBox);
frame.setVisible(true);
frame.setSize(300, 150);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
//centerFrame();
}
public void attemptConnect()
{
if(i==0)
{
i++;
Object[] services = getServiceList();
try {
comboBox = new JComboBox<Object>(services);
if (!services.toString().equalsIgnoreCase("Cannot Load Services"))
comboBox.addActionListener(new MyListListener());
}
catch(Exception ex) {
System.out.println("Cannot Establish Connection");
}
}
}
public void centerFrame()
{
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int x = (int) (d.getWidth()-frame.getWidth() / 2);
int y = (int) (d.getHeight()-frame.getHeight() / 2);
frame.setLocation(x, y);
}
public Object[] getServiceList()
{
boolean connectionsuccess = false;
Object[] objList = null;
try {
Registry rs = LocateRegistry.getRegistry("127.0.0.1", 9797); //CHANGE TO 192.168.1.97
server = (RemoteService) rs.lookup("RService");
connectionsuccess = true;
}
catch(Exception ex) {
Object[] options = {"Retry","Cancel"};
int o = JOptionPane.showOptionDialog(frame, "Cannot Establish Connection To The Server. \n Do You Want To Retry?", "Connection Error", JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE, null, options, options[0]);
if(o==0)
{
i=0;
attemptConnect();
}
else
{
i=1;
return error;
}
}
if(connectionsuccess) {
try {
objList = server.getServiceList();
}
catch(Exception ex) {
Object[] options = {"Retry","Cancel"};
int o = JOptionPane.showOptionDialog(frame, "Cannot Fetch Services List From The Server. \n Do You Want To Retry?", "Fetch Error", JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE, null, options, options[0]);
if(o==0)
{
i=0;
attemptConnect();
}
else
{
i=1;
return error;
}
}
}
return objList;
}
public void loadService(Object SvcKey)
{
try {
System.out.println(" I am going to send key: " + SvcKey);
Service svc = (Service) server.getService(SvcKey); //THIS IS CAUSING THE ERROR!
System.out.println("i am yet working"); //THIS LINE IS NOT WORKING
mainPanel.removeAll();
//frame.setContentPane(svc.getGuiPanel());
mainPanel.add(svc.getGuiPanel());
mainPanel.validate();
mainPanel.repaint();
frame.pack();
frame.setMinimumSize(new Dimension(300,150));
}
catch(Exception ex) {
Object[] options = {"Retry","Cancel"};
int o = JOptionPane.showOptionDialog(frame, "Cannot Load The Service From The Server. \n Do You Want To Retry?", "Connection Error", JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE, null, options, options[0]);
if(o==0)
{
new MyListListener();
}
else
{
i=1;
frame.repaint();
}
}
}
public class MyListListener implements ActionListener
{
public void actionPerformed(ActionEvent ev)
{
Object selection = comboBox.getSelectedItem();
System.out.println(comboBox.getSelectedItem()); //DO NOT FORGET TO TEST THIS!
loadService(selection);
}
}
public static void main(String[] args)
{
Client cl = new Client();
cl.buildGUI();
}
}
StartServer.java(实例化 RSimpl 对象并启动服务器)
package testrmi;
import java.net.InetAddress;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class StartServer {
public static void main(String[] args)
{
try {
RSimpl obj = new RSimpl();
RemoteService stub = (RemoteService) UnicastRemoteObject.exportObject(obj, 0);
System.setProperty("java.rmi.server.hostname","192.168.1.97");
//RemoteService rs = new RSimpl();
Registry r = LocateRegistry.getRegistry(9797);
r.rebind("RService", stub);
System.out.println("Remote Service Is Running");
System.out.println(""+ InetAddress.getLocalHost().getHostAddress());
}
catch (Exception ex) {
ex.printStackTrace();
System.out.println("Sorry, Cannot Start Remote Service");
}
}
}
Calculator.java(计算器服务,无需勾选)
package testrmi;
import javax.script.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.Serializable;
public class Calculator implements Service, Serializable {
JPanel mainPanel;
public JPanel getGuiPanel()
{
mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
//JPanel p1 = new JPanel();
//p1.setLayout(new GridLayout(4,4));
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
JPanel p4 = new JPanel();
final JTextField t = new JTextField(10);
t.setEditable(false);
t.setBackground(Color.green);
t.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
Font myFont = new Font("MS Sans Serif", Font.BOLD, 24);
t.setFont(myFont);
mainPanel.add(t,BorderLayout.NORTH);
final JButton n1 = new JButton("1");
n1.setFocusable(false);
n1.setFont(myFont);
n1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String num1 = n1.getText();
String global = t.getText();
global = global.concat(num1);
t.setText(global);
}
});
final JButton n2 = new JButton("2");
n2.setFocusable(false);
n2.setFont(myFont);
n2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String num1 = n2.getText();
String global = t.getText();
global = global.concat(num1);
t.setText(global);
}
});
final JButton n3 = new JButton("3");
n3.setFocusable(false);
n3.setFont(myFont);
n3.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String num1 = n3.getText();
String global = t.getText();
global = global.concat(num1);
t.setText(global);
}
});
final JButton n4 = new JButton("4");
n4.setFocusable(false);
n4.setFont(myFont);
n4.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String num1 = n4.getText();
String global = t.getText();
global = global.concat(num1);
t.setText(global);
}
});
final JButton n5 = new JButton("5");
n5.setFocusable(false);
n5.setFont(myFont);
n5.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String num1 = n5.getText();
String global = t.getText();
global = global.concat(num1);
t.setText(global);
}
});
final JButton n6 = new JButton("6");
n6.setFocusable(false);
n6.setFont(myFont);
n6.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String num1 = n6.getText();
String global = t.getText();
global = global.concat(num1);
t.setText(global);
}
});
final JButton n7 = new JButton("7");
n7.setFocusable(false);
n7.setFont(myFont);
n7.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String num1 = n7.getText();
String global = t.getText();
global = global.concat(num1);
t.setText(global);
}
});
final JButton n8 = new JButton("8");
n8.setFocusable(false);
n8.setFont(myFont);
n8.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String num1 = n8.getText();
String global = t.getText();
global = global.concat(num1);
t.setText(global);
}
});
final JButton n9 = new JButton("9");
n9.setFocusable(false);
n9.setFont(myFont);
n9.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String num1 = n9.getText();
String global = t.getText();
global = global.concat(num1);
t.setText(global);
}
});
final JButton n10 = new JButton("0");
n10.setFocusable(false);
n10.setFont(myFont);
n10.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String num1 = n10.getText();
String global = t.getText();
global = global.concat(num1);
t.setText(global);
}
});
final JButton n11 = new JButton("+");
n11.setFocusable(false);
n11.setFont(myFont);
n11.setForeground(Color.MAGENTA);
n11.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String num1 = n11.getText();
String global = t.getText();
global = global.concat(num1);
t.setText(global);
}
});
final JButton n12 = new JButton("-");
n12.setFocusable(false);
n12.setFont(myFont);
n12.setForeground(Color.MAGENTA);
n12.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String num1 = n12.getText();
String global = t.getText();
global = global.concat(num1);
t.setText(global);
}
});
final JButton n13 = new JButton("*");
n13.setFocusable(false);
n13.setFont(myFont);
n13.setForeground(Color.MAGENTA);
n13.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String num1 = n13.getText();
String global = t.getText();
global = global.concat(num1);
t.setText(global);
}
});
final JButton n14 = new JButton("/");
n14.setFocusable(false);
n14.setFont(myFont);
n14.setForeground(Color.MAGENTA);
n14.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String num1 = n14.getText();
String global = t.getText();
global = global.concat(num1);
t.setText(global);
}
});
final JButton n15 = new JButton("=");
n15.setFocusable(false);
n15.setFont(myFont);
n15.setForeground(Color.BLUE);
n15.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
//String num1 = n15.getText();
String global = t.getText();
//global = global.concat(num1);
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
try {
String s = engine.eval(global).toString();
t.setText(s);
}
catch (ScriptException e1) {
e1.printStackTrace();
}
}
});
final JButton n16 = new JButton("C");
n16.setFocusable(false);
n16.setFont(myFont);
n16.setForeground(Color.RED);
n16.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
//String num1 = n16.getText();
String global = t.getText();
global = null;
t.setText(global);
}
});
p1.add(n1);
p1.add(n2);
p1.add(n3);
p1.add(n4);
p2.add(n5);
p2.add(n6);
p2.add(n7);
p2.add(n8);
p3.add(n9);
p3.add(n10);
p3.add(n11);
p3.add(n12);
p4.add(n13);
p4.add(n14);
p4.add(n15);
p4.add(n16);
JPanel pPanel = new JPanel();
pPanel.setLayout(new BoxLayout(pPanel, BoxLayout.Y_AXIS));
pPanel.add(p1);
pPanel.add(p2);
pPanel.add(p3);
pPanel.add(p4);
mainPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
mainPanel.add(pPanel);
return mainPanel;
}
}
DiceRoll.java(DiceRoll Service,这个不用勾选)
package testrmi;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class DiceRoll implements Service {
int i = 0;
int h = 0;
JPanel mainPanel;
JButton roll;
MyDrawPanel drawPanel;
public JPanel getGuiPanel()
{
mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
roll = new JButton("Roll The Dice!");
roll.setFont(new Font("Comic Sans Ms", Font.BOLD, 16));
roll.setFocusable(false);
roll.setAlignmentX(Component.CENTER_ALIGNMENT);
roll.addActionListener(new rollListener());
drawPanel = new MyDrawPanel();
drawPanel.setPreferredSize(new Dimension(150,150));
mainPanel.add(roll);
mainPanel.add(Box.createRigidArea(new Dimension(0,10)));
mainPanel.add(drawPanel);
mainPanel.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
return mainPanel;
}
public int roll()
{
while (i==0 || i==h)
{
i = (int) (Math.random()*7);
}
h = i;
return i;
}
public class rollListener implements ActionListener
{
public void actionPerformed(ActionEvent ev)
{
int x = roll();
drawPanel.sendNum(x);
drawPanel.repaint();
}
}
public class MyDrawPanel extends JPanel
{
Graphics g;
int least = 0, x;
int fx=0, fy=0, fw=150, fh=150;
int dw=100, dh=100;
int dx=((fw-dw)/2), dy=((fh-dh)/2);
int dxc,dyc,dx1,dy1,dx2,dy2,dx3,dy3,dx4,dy4,dx5,dy5,dx6,dy6;
public void paintComponent(Graphics gn)
{
g = gn;
super.paintComponent(g);
g.setColor(Color.LIGHT_GRAY);
g.fillRect(fx, fy, fw, fh);
g.setColor(Color.WHITE);
g.fillRoundRect(dx, dy, dw, dh, 30, 30);
g.setColor(Color.BLACK); // set black for dots and border
g.drawRoundRect(dx, dy, dw, dh, 30, 30);
if(least>=1)
{
if(x==1)
{
g.fillOval(dxc, dyc, 20, 20);
}
else if(x==2)
{
g.fillOval(dx1, dy1, 20, 20);
g.fillOval(dx6, dy6, 20, 20);
}
else if(x==3)
{
g.fillOval(dx1, dy1, 20, 20);
g.fillOval(dxc, dyc, 20, 20);
g.fillOval(dx6, dy6, 20, 20);
}
else if(x==4)
{
g.fillOval(dx1, dy1, 20, 20);
g.fillOval(dx2, dy2, 20, 20);
g.fillOval(dx5, dy5, 20, 20);
g.fillOval(dx6, dy6, 20, 20);
}
else if(x==5)
{
g.fillOval(dx1, dy1, 20, 20);
g.fillOval(dx2, dy2, 20, 20);
g.fillOval(dxc, dyc, 20, 20);
g.fillOval(dx5, dy5, 20, 20);
g.fillOval(dx6, dy6, 20, 20);
}
else if(x==6)
{
g.fillOval(dx1, dy1, 20, 20);
g.fillOval(dx2, dy2, 20, 20);
g.fillOval(dx3, dy3, 20, 20);
g.fillOval(dx4, dy4, 20, 20);
g.fillOval(dx5, dy5, 20, 20);
g.fillOval(dx6, dy6, 20, 20);
}
}
}
public void sendNum(int xx)
{
least = 1;
x = xx;
// REMEMBER: dx+40=CENTER_X and dy+40=CENTER_Y because dice size 100, dot size 20
dxc=dx+40;
dyc=dy+40;
dx1=dx+10;
dy1=dy+10;
dx2=dx+70;
dy2=dy+10;
dx3=dx+10;
dy3=dy+40;
dx4=dx+70;
dy4=dy+40;
dx5=dx+10;
dy5=dy+70;
dx6=dx+70;
dy6=dy+70;
}
} // close class MyDrawPanel
}
DigitalClock1.java(无需检查——这些仅用于编译目的)
package testrmi;
import java.awt.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import java.awt.event.ActionEvent;
public class DigitalClock1 implements Service
{
public JPanel getGuiPanel()
{
SimpleDigitalClock clock1 = new SimpleDigitalClock();
return clock1;
}
static class SimpleDigitalClock extends JPanel
{
String stringTime;
int hour, minute, second;
String aHour = "";
String bMinute = "";
String cSecond = "";
public void setStringTime(String abc)
{
this.stringTime = abc;
}
public int Number(int a, int b)
{
return (a <= b) ? a : b;
}
SimpleDigitalClock()
{
Timer t = new Timer(1000, new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
repaint();
}
});
t.start();
}
@Override
public void paintComponent(Graphics v)
{
super.paintComponent(v);
Calendar rite = Calendar.getInstance();
hour = rite.get(Calendar.HOUR_OF_DAY);
minute = rite.get(Calendar.MINUTE);
second = rite.get(Calendar.SECOND);
if (hour < 10)
{
this.aHour = "0";
}
if (hour >= 10)
{
this.aHour = "";
}
if (minute < 10)
{
this.bMinute = "0";
}
if (minute >= 10)
{
this.bMinute = "";
}
if (second < 10)
{
this.cSecond = "0";
}
if (second >= 10)
{
this.cSecond = "";
}
setStringTime(aHour + hour + ":" + bMinute+ minute + ":" + cSecond + second);
v.setColor(Color.BLACK);
int length = Number(this.getWidth(),this.getHeight());
Font Font1 = new Font("Comic Sans MS", Font.PLAIN, length / 5);
v.setFont(Font1);
v.drawString(stringTime, (int) length/6, length/2);
}
@Override
public Dimension getPreferredSize()
{
return new Dimension(200, 200);
}
}
}
我正在start rmiregistry 9797
从testrmi
目录(包)所在的目录运行。然后我java testrmi.StartServer
从同一个目录运行。我得到服务器正在运行消息,然后我从另一个目录运行客户端,但具有相同的包名,仅包含 Client.class、RemoteService.class 和 Service.class;客户端启动正常,显示所有三个服务,但是当我从列表中选择时,我收到异常错误“无法加载服务,重试?”。
注意:如果我在客户端包目录中复制服务(calculator.class、diceroll.class 和 digitalclock1.class),客户端会正确加载服务。我不希望客户端直接访问服务而不连接到服务器。