package dailyBot.control.connection; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import dailyBot.control.DailyLog; public class SocketConnection { static class SocketHelper { private static final Map <String, SocketHelper> instanceMap = new ConcurrentHashMap <String, SocketHelper>(); private static final ExecutorService executor = Executors.newSingleThreadExecutor(); private static SocketHelper getInstance(String hostname, int port) { String key = hostname + " " + port; if(!instanceMap.containsKey(key)) instanceMap.put(key, new SocketHelper(hostname, port)); return instanceMap.get(key); } private final String hostname; private final int port; private Socket socket; private PrintWriter out; private BufferedReader in; public SocketHelper(String hostname, int port) { this.hostname = hostname; this.port = port; } private synchronized void clearSocket() { try { if(socket != null) socket.close(); } catch(Exception e) { } socket = null; } private synchronized void ensureSocketOpen(int number) { if(number == 10) throw new RuntimeException("Conexion por socket imposible despues de 10 intentos: " + hostname + ":" + port); if(socket == null || (!socket.isConnected()) || (socket.isClosed())) { clearSocket(); try { socket = new Socket(hostname, port); socket.setSoTimeout(10000); out = new PrintWriter(socket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); } catch(Exception e) { clearSocket(); } ensureSocketOpen(number + 1); } else { try { out.println("test"); out.flush(); if(in.readLine().equals("oK")) return; } catch(Exception e) { } clearSocket(); ensureSocketOpen(number + 1); } } public synchronized String sendAndReceive(String... values) throws IOException { ensureSocketOpen(0); for(String value : values) { out.println(value); out.flush(); } return in.readLine(); } } public static String sendAndReceive(String hostname, int port, final String... values) { final SocketHelper helper = SocketHelper.getInstance(hostname, port); Future <String> future = SocketHelper.executor.submit(new Callable <String>() { @Override public String call() throws Exception { return helper.sendAndReceive(values); } }); try { return future.get(120, TimeUnit.SECONDS); } catch(Exception e) { DailyLog.logError("Error en comunicacion por socket " + hostname + ":" + port + " " + e.getMessage()); throw new RuntimeException(e); } } }