Прошу прощения, если ошибся темой.
Прошу помочь разобраться с сервисом, реализованным через RMI.
Есть программа:
--удаленный интерфейс
import java.rmi.Remote; import java.rmi.RemoteException; public interface ServiceServer extends Remote { //получаем список сервисов Object[] getServiceList() throws RemoteException; //получаем сервис Service getService(Object serviceKey) throws RemoteException; }
--реализация удаленного интерфейса
import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; import java.util.HashMap; public class ServiceServerImpl extends UnicastRemoteObject implements ServiceServer { HashMap serviceList; public ServiceServerImpl() throws RemoteException { setUpServices(); } private void setUpServices() { serviceList = new HashMap(); serviceList.put("Dice Rolling Service", new DiceService()); serviceList.put("Day of the Week Service", new DayOfTheWeekService()); serviceList.put("Visual Music Service", new MiniMusicService()); } public Object[] getServiceList() throws RemoteException { System.out.println("in remote"); return serviceList.keySet().toArray(); } public Service getService(Object serviceKey) throws RemoteException { Service theService = (Service) serviceList.get(serviceKey); return theService; } public static void main (String[] args) { try { Naming.rebind("ServiceServer", new ServiceServerImpl()); } catch (Exception ex){ ex.printStackTrace(); } System.out.println("Remote service is running"); } }
--интерфейс для классов которые должны вернуться клиенту (сервисы)
import javax.swing.*; import java.io.Serializable; public interface Service extends Serializable { public JPanel getGuiPanel(); }
--классы, реализующие Service
import java.awt.event.ActionListener; public class MiniMusicService implements Service { MyDrawPanel myPanel; JPanel mainPanel; public JPanel getGuiPanel() { mainPanel = new JPanel(); myPanel = new MyDrawPanel(); JButton playItButton = new JButton("Play it"); playItButton.addActionListener(new PlayItLictener()); mainPanel.add(myPanel); mainPanel.add(playItButton); return mainPanel; } //ActionListener for JButton public class PlayItLictener implements ActionListener { public void actionPerformed(ActionEvent actionEvent) { try { Sequencer sequencer = MidiSystem.getSequencer(); sequencer.open(); sequencer.addControllerEventListener(myPanel, new int [] {127}); Sequence sequence = new Sequence(Sequence.PPQ, 4); Track track = sequence.createTrack(); for (int i = 0; i < 100; i++) { int rNum = (int) ((Math.random()*50)+1); if (rNum < 38) { track.add(makeEvent(144,1,rNum, 100, i)); track.add(makeEvent(176, 1, 127, 0, i)); track.add(makeEvent(128,1, rNum, 100, i+2)); } } sequencer.setSequence(sequence); sequencer.start(); sequencer.setTempoInBPM(220); } catch (Exception ex) { ex.printStackTrace(); } } public MidiEvent makeEvent(int comd, int chan,int one, int two, int tick) { MidiEvent event = null; try { ShortMessage m = new ShortMessage(); m.setMessage(comd,chan,one,two); event = new MidiEvent(m, tick); } catch (Exception ex) {ex.printStackTrace();} return event; } } class MyDrawPanel extends JPanel implements ControllerEventListener { boolean msg = false; public void controlChange(ShortMessage shortMessage) { msg = true; repaint(); } public Dimension getPreferredSize() { return new Dimension(300, 300); } public void paintComponent(Graphics g) { if (msg) { Graphics2D g2 = (Graphics2D) g; int r = (int) (Math.random() * 250); int gr = (int) (Math.random() * 250); int b = (int) (Math.random() * 250); g.setColor(new Color(r, gr, b)); int ht = (int) ((Math.random() * 120) + 10); int width = (int) ((Math.random() * 120) + 10); int x = (int) ((Math.random() * 40) + 10); int y = (int) ((Math.random() * 40) + 10); g.fillRect(x, y, ht, width); msg = false; } } } }
import java.awt.event.ActionListener; public class DiceService implements Service { JLabel label; JComboBox numOfDice; JPanel panel; public JPanel getGuiPanel() { panel = new JPanel(); JButton button = new JButton("Roll..."); String[] choices = {"1","2","3","4","5"}; numOfDice = new JComboBox(choices); label = new JLabel("dice values here"); button.addActionListener(new RollEmListener()); panel.add(numOfDice); panel.add(label); panel.add(button); return panel; } public class RollEmListener implements ActionListener { public void actionPerformed(ActionEvent ev) { //Бросаем Кости String diceOutput = ""; String selection = (String) numOfDice.getSelectedItem(); int numOfDiceToRoll = Integer.parseInt(selection); for (int i = 0; i < numOfDiceToRoll; i++) { int r = (int) ((Math.random()*6) + 1); diceOutput += (" " + r); } label.setText(diceOutput); } } }
import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.DateFormatSymbols; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; public class DayOfTheWeekService implements Service { JLabel outputLable; JComboBox month; JTextField day; JTextField year; public JPanel getGuiPanel() { JPanel panel = new JPanel(); JButton button = new JButton("Do it"); button.addActionListener(new DoItListener()); outputLable = new JLabel("Date appears here"); DateFormatSymbols dateStuff = new DateFormatSymbols(); month = new JComboBox(dateStuff.getMonths()); day = new JTextField(8); year = new JTextField(8); JPanel inputPanel = new JPanel(new GridLayout(3,2)); inputPanel.add(new JLabel("Month")); inputPanel.add(month); inputPanel.add(new JLabel("Day")); inputPanel.add(day); inputPanel.add(new JLabel("Year")); inputPanel.add(year); panel.add(inputPanel); panel.add(button); panel.add(outputLable); return panel; } public class DoItListener implements ActionListener { public void actionPerformed(ActionEvent actionEvent) { int monthNum = month.getSelectedIndex(); int dayNum = Integer.parseInt(day.getText()); int yearNum = Integer.parseInt(year.getText()); Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.MONTH,monthNum); calendar.set(Calendar.DAY_OF_MONTH,dayNum); calendar.set(Calendar.YEAR,yearNum); Date date = calendar.getTime(); String dayOfWeek = new SimpleDateFormat("EEEE").format(date); outputLable.setText(dayOfWeek); } } }
--Ну и на конец Клиент
import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.rmi.Naming; public class ServiceBrowser { JPanel mainPanel; JComboBox serviceList; ServiceServer server; public static void main(String[] args) { new ServiceBrowser().buildGUI(); } public void buildGUI() { JFrame frame = new JFrame("RMI browser"); mainPanel = new JPanel(); frame.getContentPane().add(BorderLayout.CENTER,mainPanel); Object[] services = getServicesList(); //выполняется поиск по RMI-реестру, получаем заглушку и вызываем getServicesList serviceList = new JComboBox(services); frame.getContentPane().add(BorderLayout.NORTH,serviceList); serviceList.addActionListener(new MyListListener()); frame.setSize(500,500); frame.setVisible(true); } Object[] getServicesList() { Object obj = null; Object[] services = null; try { obj = Naming.lookup("rmi://127.0.0.1/ServiceServer"); //поиск по RMI-реестру и получение заглушки } catch (Exception ex) { ex.printStackTrace(); } server = (ServiceServer) obj; try { services = server.getServiceList(); // вызываем из заглушки метод getServiceList() } catch (Exception ex) { ex.printStackTrace(); } return services; } class MyListListener implements ActionListener { public void actionPerformed(ActionEvent actionEvent) { Object selection = serviceList.getSelectedItem(); loadService(selection); } } void loadService(Object serviceSelection) { try { Service svc = server.getService(serviceSelection); //вызов getService из удаленного сервера mainPanel.removeAll(); mainPanel.add(svc.getGuiPanel()); mainPanel.validate(); mainPanel.repaint(); } catch (Exception ex) { ex.printStackTrace(); } } }
Прошу помочь собрать это все в кучу. На сколько я понимаю у меня все практически готово, остается только создать скелет и заглушку класса ServiceServerImpl с помощью rmic (к сожалению у меня это пока не получилось , в терминале выскакивает ошибка что класс не найден) + На сколько я понимаю с текущей реализацией - запуск rmiregistry не нужен, в связи с чем я уже компилирую классы для клиента и сервера:
для клиента : ServiceServer + ServiceServerImpl_заглушка + ServiceBrowser
для сервера : ServiceServer + ServiceServerImpl_заглушка + ServiceServerImpl_скелет + ServiceServerImpl + Service + 3_класса_реализующих_Service
Все верно?