package com.framsticks.core; import com.framsticks.hosting.InstanceClient; import com.framsticks.util.dispatching.Thread; import org.apache.commons.configuration.Configuration; import org.apache.log4j.Logger; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.HashSet; import java.util.Set; import com.framsticks.util.dispatching.RunAt; /** * @author Piotr Sniegowski */ public abstract class LocalInstance extends Instance { private static final Logger log = Logger.getLogger(LocalInstance.class.getName()); public LocalInstance() { } @Override public void configure(Configuration config) { Integer accept = config.getInteger("accept", null); if (accept != null) { try { acceptSocket = new ServerSocket(); acceptSocket.setReuseAddress(true); acceptThread = new Thread(name + "-accept").start(); tryBind(accept); } catch (IOException e) { log.fatal("failed to create accept socket: " + e); } } } protected final Set clients = new HashSet(); ServerSocket acceptSocket; public static class Accept { }; Thread acceptThread; protected void acceptNext() { acceptThread.invokeLater(new RunAt() { @Override public void run() { try { final Socket socket = acceptSocket.accept(); assert socket != null; log.debug("accepted socket: " + socket.getInetAddress().getHostAddress()); invokeLater(new RunAt() { @Override public void run() { InstanceClient client = new InstanceClient(LocalInstance.this, socket); clients.add(client); log.info("client connected: " + client); } }); } catch (IOException e) { log.error("failed to accept socket: " + e); } acceptNext(); } }); } public void tryBind(final Integer accept) { acceptThread.invokeLater(new RunAt() { @Override public void run() { try { acceptSocket.bind(new InetSocketAddress(accept)); log.debug("started accepting on port " + accept); acceptNext(); } catch (IOException e) { log.fatal("failed to accept on port " + accept + ": " + e); } try { java.lang.Thread.sleep(1000); } catch (InterruptedException ignored) { } tryBind(accept); } }); } }