/** Transport connected. {@link IOTransport} calls this when a connection is established. */ public void transportConnected() { setState(STATE_READY); if (reconnectTask != null) { reconnectTask.cancel(); reconnectTask = null; } resetTimeout(); synchronized (outputBuffer) { if (transport.canSendBulk()) { ConcurrentLinkedQueue<String> outputBuffer = this.outputBuffer; this.outputBuffer = new ConcurrentLinkedQueue<String>(); try { // DEBUG String[] texts = outputBuffer.toArray(new String[outputBuffer.size()]); log.debug("Bulk start:"); for (String text : texts) { log.debug("> " + text); } log.debug("Bulk end"); // DEBUG END transport.sendBulk(texts); } catch (IOException e) { this.outputBuffer = outputBuffer; } } else { String text; while ((text = outputBuffer.poll()) != null) { sendPlain(text); } } this.keepAliveInQueue = false; } }
/** * Transport disconnected. {@link IOTransport} calls this when a connection has been shut down. */ public void transportDisconnected() { log.debug("transportDisconnected called!"); this.lastException = null; setState(STATE_INTERRUPTED); reconnect(); }
/** * Forces a reconnect. This had become useful on some android devices which do not shut down * TCP-connections when switching from HSDPA to Wifi */ public void reconnect() { log.info("reconnect called!"); synchronized (this) { if (getState() != STATE_INVALID) { invalidateTransport(); setState(STATE_INTERRUPTED); if (reconnectTask != null) { reconnectTask.cancel(); } reconnectTask = new ReconnectTask(); backgroundTimer.schedule(reconnectTask, 1000); } } }
/** Cleanup. IOConnection is not usable after calling this. */ private void cleanup() { setState(STATE_INVALID); if (transport != null) { transport.disconnect(); } sockets.clear(); synchronized (connections) { List<IOConnection> con = connections.get(urlStr); if (con != null && con.size() > 1) { con.remove(this); } else { connections.remove(urlStr); } } log.debug("cleanup"); backgroundTimer.cancel(); }
/** Connect transport */ private void connectTransport() { if (getState() == STATE_INVALID) { return; } setState(STATE_CONNECTING); if (protocols.contains(WebSocketTransport.TRANSPORT_NAME)) { transport = WebSocketTransport.create(this.url.getProtocol() + "://" + this.url.getAuthority(), this); } else if (protocols.contains(XhrTransport.TRANSPORT_NAME)) { transport = XhrTransport.create(this.url.getProtocol() + "://" + this.url.getAuthority(), this); } else { error( new SocketIOException( "Server supports no available transports. You should reconfigure the server to support a available transport")); return; } transport.connect(); }
/** Handshake. */ private void handshake() { URL url; String response; URLConnection connection; try { setState(STATE_HANDSHAKE); url = new URL( this.url.getProtocol() + "://" + this.url.getAuthority() + SOCKET_IO_1 + (this.url.getQuery() == null ? "" : "?" + this.url.getQuery())); connection = url.openConnection(); if (connection instanceof HttpsURLConnection) { ((HttpsURLConnection) connection).setSSLSocketFactory(sslSocketFactory); } connection.setConnectTimeout(connectTimeout); connection.setReadTimeout(connectTimeout); /* Setting the request headers */ for (Entry<Object, Object> entry : headers.entrySet()) { connection.setRequestProperty((String) entry.getKey(), (String) entry.getValue()); } log.debug("> " + connection.toString()); InputStream stream = connection.getInputStream(); Scanner in = new Scanner(stream); response = in.nextLine(); log.debug("< " + response); String[] data = response.split(":"); sessionId = data[0]; heartbeatTimeout = Long.parseLong(data[1]) * 1000; closingTimeout = Long.parseLong(data[2]) * 1000; protocols = Arrays.asList(data[3].split(",")); } catch (Exception e) { error(new SocketIOException("Error while handshaking", e)); } }
/** * Transport error. * * @param error the error {@link IOTransport} calls this, when an exception has occurred and the * transport is not usable anymore. */ public void transportError(Exception error) { this.lastException = error; setState(STATE_INTERRUPTED); reconnect(); }