package org.jgroups.demos; import org.jgroups.*; import org.jgroups.blocks.RequestOptions; import org.jgroups.blocks.ResponseMode; import org.jgroups.blocks.RpcDispatcher; import org.jgroups.util.Rsp; import org.jgroups.util.RspList; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.util.Enumeration; import java.util.Hashtable; /** * Used in conjunction with QuoteServer: a client is member of a group of quote servers which replicate * stock quotes among themselves. The client broadcasts its request (set, get quotes) and (in the case of get * waits for the first reply received (usually the one from the quote server closest to it). The client * can get and set quotes as long as a minimum of 1 server (in the group) is running. * @author Bela Ban */ public class QuoteClient extends Frame implements WindowListener, ActionListener, MembershipListener { static final String channel_name="Quotes"; RpcDispatcher disp; Channel channel; final Button get=new Button("Get"); final Button set=new Button("Set"); final Button quit=new Button("Quit"); final Button get_all=new Button("All"); final Label stock=new Label("Stock"); final Label value=new Label("Value"); final Label err_msg=new Label("Error"); final TextField stock_field=new TextField(); final TextField value_field=new TextField(); final java.awt.List listbox=new java.awt.List(); final Font default_font=new Font("Helvetica", Font.PLAIN, 12); static final String props=null; // default stack from JChannel public QuoteClient() { super(); try { channel=new JChannel(props); channel.setDiscardOwnMessages(true); disp=new RpcDispatcher(channel, null, this, this); channel.connect(channel_name); } catch(Exception e) { System.err.println("QuoteClient(): " + e); } addWindowListener(this); } private void showMsg(String msg) { err_msg.setText(msg); err_msg.setVisible(true); } private void clearMsg() { err_msg.setVisible(false); } public void start() { setLayout(null); setSize(400, 300); setFont(default_font); stock.setBounds(new Rectangle(10, 30, 60, 30)); value.setBounds(new Rectangle(10, 60, 60, 30)); stock_field.setBounds(new Rectangle(100, 30, 100, 30)); value_field.setBounds(new Rectangle(100, 60, 100, 30)); listbox.setBounds(210, 30, 150, 160); err_msg.setBounds(new Rectangle(10, 200, 350, 30)); err_msg.setFont(new Font("Helvetica", Font.ITALIC, 12)); err_msg.setForeground(Color.red); err_msg.setVisible(false); get.setBounds(new Rectangle(10, 250, 80, 30)); set.setBounds(new Rectangle(100, 250, 80, 30)); quit.setBounds(new Rectangle(190, 250, 80, 30)); get_all.setBounds(new Rectangle(280, 250, 80, 30)); get.addActionListener(this); set.addActionListener(this); quit.addActionListener(this); get_all.addActionListener(this); add(stock); add(value); add(stock_field); add(value_field); add(err_msg); add(get); add(set); add(quit); add(get_all); add(listbox); // stock_field.requestFocus(); setVisible(true); } public void windowActivated(WindowEvent e) { } public void windowClosed(WindowEvent e) { } public void windowClosing(WindowEvent e) { System.exit(0); } public void windowDeactivated(WindowEvent e) { } public void windowDeiconified(WindowEvent e) { } public void windowIconified(WindowEvent e) { } public void windowOpened(WindowEvent e) { } public void actionPerformed(ActionEvent e) { String command=e.getActionCommand(); try { if(command.equals("Get")) { String stock_name=stock_field.getText(); if(stock_name == null || stock_name.length() == 0) { showMsg("Stock name is empty !"); return; } showMsg("Looking up value for " + stock_name + ':'); RspList<Object> quotes=disp.callRemoteMethods(null, "getQuote", new Object[]{stock_name}, new Class[]{String.class}, new RequestOptions(ResponseMode.GET_ALL, 10000)); Float val=null; for(Rsp<Object> rsp: quotes.values()) { Object quote=rsp.getValue(); if(quote == null || quote instanceof Throwable) continue; val=(Float)quote; break; } if(val != null) { value_field.setText(val.toString()); clearMsg(); } else { value_field.setText(""); showMsg("Value for " + stock_name + " not found"); } } else if(command.equals("Set")) { String stock_name=stock_field.getText(); String stock_val=value_field.getText(); if(stock_name == null || stock_val == null || stock_name.length() == 0 || stock_val.length() == 0) { showMsg("Stock name and value have to be present to enter a new value"); return; } Float val=new Float(stock_val); disp.callRemoteMethods(null, "setQuote", new Object[]{stock_name, val}, new Class[]{String.class, Float.class}, new RequestOptions(ResponseMode.GET_FIRST, 0)); showMsg("Stock " + stock_name + " set to " + val); } else if(command.equals("All")) { listbox.removeAll(); showMsg("Getting all stocks:"); RspList<Object> rsp_list=disp.callRemoteMethods(null, "getAllStocks", null, null, new RequestOptions(ResponseMode.GET_ALL, 5000)); System.out.println("rsp_list is " + rsp_list); Hashtable all_stocks=null; for(Rsp rsp: rsp_list.values()) { Object obj=rsp.getValue(); if(obj == null || obj instanceof Throwable) continue; all_stocks=(Hashtable)obj; break; } if(all_stocks == null) { showMsg("No stocks found"); return; } clearMsg(); listbox.removeAll(); String key; Float val; for(Enumeration en=all_stocks.keys(); en.hasMoreElements();) { key=(String)en.nextElement(); val=(Float)all_stocks.get(key); if(val == null) continue; listbox.add(key + ": " + val.toString()); } } else if(command.equals("Quit")) { setVisible(false); channel.close(); System.exit(0); } else System.out.println("Unknown action"); } catch(Exception ex) { value_field.setText(""); ex.printStackTrace(); showMsg(ex.toString()); } } public void setQuote(String stock_name, Float value) { ; } public void printAllStocks() { } public void viewAccepted(View new_view) { setTitle("Members in " + channel_name + ": " + (new_view.size() - 1)); } public void suspect(Address suspected_mbr) { } public void block() { } public void unblock() { } public static void main(String args[]) { QuoteClient client=new QuoteClient(); client.start(); } }