public void close() { boolean wasClosed = false; synchronized (this) { if (!isClosed()) { try { if (session != null) { session.setStatus(Session.STATUS_CLOSED); } synchronized (writer) { try { // Register that we started sending data on the connection writeStarted(); writer.write("</stream:stream>"); if (flashClient) { writer.write('\0'); } writer.flush(); } catch (IOException e) { } finally { // Register that we finished sending data on the connection writeFinished(); } } } catch (Exception e) { Log.error( LocaleUtils.getLocalizedString("admin.error.close") + "\n" + this.toString(), e); } closeConnection(); wasClosed = true; } } if (wasClosed) { notifyCloseListeners(); } }
/** * Forces the connection to be closed immediately no matter if closing the socket takes a long * time. This method should only be called from {@link SocketSendingTracker} when sending data * over the socket has taken a long time and we need to close the socket, discard the connection * and its session. */ private void forceClose() { if (session != null) { // Set that the session is closed. This will prevent threads from trying to // deliver packets to this session thus preventing future locks. session.setStatus(Session.STATUS_CLOSED); } closeConnection(); // Notify the close listeners so that the SessionManager can send unavailable // presences if required. notifyCloseListeners(); }