-2

我一直在绞尽脑汁试图找出问题所在,我很确定服务器连接建立得很整齐。我什至放了一些系统打印以确保发送和接收对象。让我先发布我的代码。

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 9797testrmi目录(包)所在的目录运行。然后我java testrmi.StartServer从同一个目录运行。我得到服务器正在运行消息,然后我从另一个目录运行客户端,但具有相同的包名,仅包含 Client.class、RemoteService.class 和 Service.class;客户端启动正常,显示所有三个服务,但是当我从列表中选择时,我收到异常错误“无法加载服务,重试?”。

注意:如果我在客户端包目录中复制服务(calculator.class、diceroll.class 和 digitalclock1.class),客户端会正确加载服务。我不希望客户端直接访问服务而不连接到服务器。

4

1 回答 1

1

如果您希望能够将不在客户端类路径中的可序列化对象返回给客户端,则需要使用RMI 代码库功能,其中需要您部署代码库服务器,并SecurityManager在客户端使用 a。

于 2017-07-19T11:17:49.347 回答