package javaforce.jbus; /** * Created : Apr 9, 2012 * * @author pquiring */ import java.io.*; import java.net.*; import java.util.*; import javaforce.*; public class JBusServer extends Thread { public static int port; public static volatile boolean ready = false; private Vector<Client> clients = new Vector<Client>(); private boolean active = true; private ServerSocket ss; private Object lock = new Object(); public JBusServer() { port = 777; } public JBusServer(int port) { this.port = port; } public void run() { try { ss = new ServerSocket(port, 1024, InetAddress.getByName("127.0.0.1")); JFLog.log("JBusServer starting on port " + port); ready = true; while (active) { try { Socket s = ss.accept(); //reject s if it's not localhost String ip = s.getInetAddress().toString().substring(1); //strip leading '/' if (ip.equals("127.0.0.1") || ip.equals("0:0:0:0:0:0:0:1")) { //ip4 || ip6 - localhost Client client = new Client(s); client.start(); } else { JFLog.log("JBus : Unauthorized client:" + ip); } } catch (Exception e1) { JFLog.log(e1); } } ss.close(); } catch (Exception e2) { JFLog.log(e2); } } public void close() { if (ss == null) { return; } active = false; try { ss.close(); } catch (Exception e) { } ss = null; } private class Client extends Thread { private String pack; private Socket s; private InputStream is; private OutputStream os; public Client(Socket s) { this.s = s; try { is = s.getInputStream(); os = s.getOutputStream(); } catch (Exception e) { JFLog.log(e); } } public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(is)); while (s.isConnected()) { String cmd = br.readLine(); if (cmd == null) { break; } doCmd(cmd); } } catch (Exception e) { JFLog.log(e); } synchronized (lock) { clients.remove(this); } if (pack != null) { JFLog.log("JBus : package unregistered:" + pack); } } private void doCmd(String cmd) throws Exception { boolean broadcast = false; if (cmd.startsWith("cmd.")) { if (cmd.startsWith("cmd.package=")) { if (pack != null) { return; //ignore } pack = cmd.substring(12); JFLog.log("JBus : package registered:" + pack); synchronized (lock) { clients.add(this); } return; } else if (cmd.startsWith("cmd.broadcast=")) { broadcast = true; cmd = cmd.substring(14); } else { //unknown cmd JFLog.log("JBus : unknown cmd:" + cmd); return; } } //must be a remote function call //general format : org.package.func(args) //supported args : "String", int int b1 = cmd.indexOf("("); int b2 = cmd.length() - 1; // String args = cmd.substring(b1+1, b2); String packFunc = cmd.substring(0, b1); int idx = packFunc.lastIndexOf('.'); if (idx == -1) { return; } String call_pack = packFunc.substring(0, idx); String call_func = packFunc.substring(idx + 1); cmd += "\n"; synchronized (lock) { for (int a = 0; a < clients.size(); a++) { Client client = clients.get(a); if (client.pack.equals(call_pack) || (broadcast && client.pack.startsWith(call_pack))) { client.os.write(cmd.getBytes()); client.os.flush(); return; } } } JFLog.log("JBus : call to unregistered package.func:" + call_pack + "." + call_func); } public boolean call(String pack, String func, String args) { return call(pack + "." + func + "(" + args + ")\n"); } public boolean call(String pfa) { try { os.write(pfa.getBytes()); os.flush(); return true; } catch (Exception e) { JFLog.log(e); return false; } } } /** * Broadcasts to call clients that <b>start</b> with the <i>pack</i>. */ public void broadcast(String pack, String func, String args) { synchronized (lock) { for (int a = 0; a < clients.size(); a++) { Client client = clients.get(a); if (client.pack != null) { if (client.pack.startsWith(pack)) { client.call(client.pack, func, args); } } } } } /** Checks if a JBusServer is running. */ public static boolean present() { JBusClient client = new JBusClient(null, null); client.setQuiet(true); client.start(); boolean present = client.ready(); if (present) { client.close(); } return present; } public static void main(String args[]) { serviceStart(args); } //Win32 Service private static JBusServer svr; public static void serviceStart(String args[]) { svr = new JBusServer(); svr.start(); } public static void serviceStop() { JFLog.log("Stopping service"); svr.close(); } }