!747 m { static Set peers = synchroTreeSet(); // only those with a running web server are listed p { makeAndroid("Networking module!"); startAWebServer(8888); for (S ip : getMyIPs()) discover(ip); // You are your own peer! :) connectToGateway(); } static synchronized S answer(S s) { if (match3("how many peers", s)) return "" + peers.size(); if (match3("what is a peer", s)) return "an ip address that had a port 8888 web server at some point"; if (match3("list peers", s)) return structure(peers); if (match3("ok", s)) return "ok!"; return null; } static void startAWebServer(int port) { Class webserver = hotwire("#1000842"); set(webserver, "port", port); set(webserver, "onClient", new Object() { public Object run(Object... args) { /* args are: final String uri, final Method method, final Map header, final Map parms, final Map files */ Map header = (Map) args[2]; print("header: " + structure(header)); S ip = header.get("remote-addr"); discover(ip); return null; } }); call(webserver, "start"); } static void connectToGateway() { L ips = detectGateways(); if (ips.isEmpty()) print("No gateways found."); for (String ip : ips) discover(ip); } static void discover(S ip) { if (peers.contains(ip)) return; print("Possible peer found: " + ip + " - connecting"); try { String page = loadPage("http://" + ip + ":8888"); // TODO: HEAD is enough peers.add(ip); print("OK, peer found: " + ip + " - peers now: " + structure(peers)); } catch (Throwable e) { print("Could not load home page of " + ip + ", not adding as peer. Peers: " + structure(peers)); } } }