public Server( int port, IServiceLayer serviceLayer, Set<ConfiguredServer> configuredServers, boolean isWhiteListed, int maximumThreads) { if (configuredServers == null) { throw new IllegalArgumentException("The configuredServers argument is invalid (null)."); } this.isServerRunning = true; this.threads = new LinkedList<Connection>(); // Properties this.port = port; this.configuredServers = configuredServers; this.maximumThreads = maximumThreads; this.handshakeTimeOutInMilliseconds = 1000; this.frameTimeOutToleranceInMilliseconds = 3000; this.maximumFragmentationSize = 2; this.checkOrigin = true; this.pingable = true; this.serviceLayer = serviceLayer; if (isWhiteListed) { this.whitelist = new HashSet<String>(); if (!loadWhiteList()) { // TODO: Create the white-list.txt and bail. Logger.severe("The white-list was not found..."); } } // Let the user know that they have not configured any servers in the config.yml. if (this.configuredServers.size() == 0) { Logger.info( "Warning: Either no servers have been configured in the config.yml to communicate with the bridge or all servers are set to restricted access."); } }
/** Attempts to load the white-list. */ private boolean loadWhiteList() { File whitelistFile = new File(Globals.PLUGIN_FOLDER + "/" + Globals.WHITE_LIST_FILENAME); if (whitelistFile.exists()) { BufferedReader br = null; try { // --- CR (10-14/12) --- Removed the try-with-resources block to support backwards // compatibility. // try (BufferedReader br = new BufferedReader(new FileReader(whitelistFile))) br = new BufferedReader(new FileReader(whitelistFile)); if (br != null) { String domain; while ((domain = br.readLine()) != null) { if (domain != "") { this.whitelist.add(domain.toUpperCase()); } } } br.close(); return true; } catch (FileNotFoundException fnfe) { } catch (IOException io) { } finally { try { br.close(); } catch (IOException io) { } } } else { // The white-list was not found so create it. try { whitelistFile.createNewFile(); } catch (IOException io) { Logger.debug( MessageFormat.format( "Cannot create \"{0}/{1}\".", Globals.PLUGIN_FOLDER, Globals.WHITE_LIST_FILENAME)); } } // END OF if(whitelistFile.exists())... return false; }
/** Begin running the websocket server. */ @Override public void run() { try { Logger.info( MessageFormat.format("WebSocketServerBridge listening on port {0}...", this.port)); serverSocket = new ServerSocket(this.port); // Waiting for the server socket to close or until the server is shutdown manually. while ((this.isServerRunning) && (!serverSocket.isClosed())) { // Wait for incoming connections. Socket socket = serverSocket.accept(); // Try to reclaim any threads if we are exceeding our maximum. // TimeComplexity: O(n) -- Where n is the number of threads valid or invalid. // NOTE: Minimal unit testing has been done here...more testing is required. if (threads.size() + 1 > this.getMaximumThreads()) { for (int i = 0; i < threads.size(); i++) { if (!threads.get(i).isAlive()) { threads.remove(i); } } } // Make sure we have enough threads before accepting. // NOTE: Minimal unit testing has been done here...more testing is required. if ((threads.size() + 1) <= this.getMaximumThreads()) { Connection t = new Connection(socket, this.serviceLayer, this); t.start(); threads.add(t); } else { Logger.debug("The server has reached its thread maximum..."); } } // END OF while ( (this.isServerRunning) && (!serverSocket.isClosed()) )... Logger.info("WebSocket server stopping..."); } catch (IOException ioException) { // --- CR (8/10/13) --- Only log the event if the server is still running. This should // prevent an error message from appearing when the server is restarted. if (this.isServerRunning) { Logger.info( MessageFormat.format("The port {0} could not be opened for WebSockets.", this.port)); Logger.debug(ioException.getMessage()); } // Close all threads. // TimeComplexity: O(n) -- Where n is the number of threads valid or invalid. for (Connection t : threads) { if (t.isAlive()) { t.close(); } } } }