/** * Disconnect a socket from the IOConnection. Shuts down this IOConnection if no further * connections are available for this IOConnection. * * @param socket the socket to be shut down */ public void unregister(SocketIO socket) { sendPlain("0::" + socket.getNamespace()); sockets.remove(socket.getNamespace()); socket.getCallback().onDisconnect(); if (sockets.size() == 0) { cleanup(); } }
/** * Populates an error to the connected {@link IOCallback}s and shuts down. * * @param e an exception */ protected void error(SocketIOException e) { // Ensure any errors during disconnect are ignored if (state != STATE_INVALID) { for (SocketIO socket : sockets.values()) { socket.getCallback().onError(e); } cleanup(); } }
/** * Transport message. {@link IOTransport} calls this, when a message has been received. * * @param text the text */ public void transportMessage(String text) { log.debug("< " + text); IOMessage message; try { message = new IOMessage(text); } catch (Exception e) { error(new SocketIOException("Garbage from server: " + text, e)); return; } resetTimeout(); switch (message.getType()) { case IOMessage.TYPE_DISCONNECT: try { findCallback(message).onDisconnect(); } catch (Exception e) { error(new SocketIOException("Exception was thrown in onDisconnect()", e)); } break; case IOMessage.TYPE_CONNECT: try { if (firstSocket != null && "".equals(message.getEndpoint())) { if (firstSocket.getNamespace().equals("")) { firstSocket.getCallback().onConnect(); } else { IOMessage connect = new IOMessage(IOMessage.TYPE_CONNECT, firstSocket.getNamespace(), ""); sendPlain(connect.toString()); } } else { findCallback(message).onConnect(); } firstSocket = null; } catch (Exception e) { error(new SocketIOException("Exception was thrown in onConnect()", e)); } break; case IOMessage.TYPE_HEARTBEAT: sendPlain("2::"); break; case IOMessage.TYPE_MESSAGE: try { findCallback(message).onMessage(message.getData(), remoteAcknowledge(message)); } catch (Exception e) { error( new SocketIOException( "Exception was thrown in onMessage(String).\n" + "Message was: " + message.toString(), e)); } break; case IOMessage.TYPE_JSON_MESSAGE: try { // test if JSON is valid by catching a parse Exception objectMapper.readValue(message.getData(), new TypeReference<Map<String, Object>>() {}); // JSONUtils.getJsonGenericMap(message.getData(), objectMapper); findCallback(message).onMessage(message.getData(), remoteAcknowledge(message)); } catch (JsonParseException e) { log.warn("Malformated JSON received: " + message.getData()); } catch (Exception e) { error( new SocketIOException( "Exception was thrown in onMessage(JSON).\n" + "Message was: " + message.toString(), e)); } break; case IOMessage.TYPE_EVENT: try { Map<String, Object> map = objectMapper.readValue( message.getData(), new TypeReference<Map<String, Object>>() {}); Object[] argsArray; if (map.containsKey("args")) { Object argsString = map.get("args"); List<Object> argObjects = objectMapper.readValue(argsString.toString(), new TypeReference<List<Object>>() {}); argsArray = new Object[argObjects.size()]; for (int i = 0; i < argObjects.size(); i++) { if (argObjects.get(i) != null) { argsArray[i] = argObjects.get(i); } } } else { argsArray = new Object[0]; } String eventName = map.get("name").toString(); try { findCallback(message).on(eventName, remoteAcknowledge(message), argsArray); } catch (Exception e) { error( new SocketIOException( "Exception was thrown in on(String, JSON[]).\n" + "Message was: " + message.toString(), e)); } } catch (JsonParseException e) { log.warn("Malformated JSON received: " + message.getData()); } catch (JsonMappingException e) { log.warn("Mapping JSON received: " + message.getData()); } catch (IOException e) { log.warn("IO Exception: " + message.getData()); } break; case IOMessage.TYPE_ACK: String[] data = message.getData().split("\\+", 2); if (data.length == 2) { try { int id = Integer.parseInt(data[0]); IOAcknowledge ack = acknowledge.get(id); if (ack == null) { log.warn("Received unknown ack packet"); } else { List<Object> argObjects = objectMapper.readValue(data[1].toString(), new TypeReference<List<Object>>() {}); Object[] argsArray = new Object[argObjects.size()]; for (int i = 0; i < argObjects.size(); i++) { if (argObjects.get(i) != null) { argsArray[i] = argObjects.get(i); } } ack.ack(argsArray); } } catch (NumberFormatException e) { log.warn( "Received malformated Acknowledge! This is potentially filling up the acknowledges!"); } catch (JsonParseException e) { log.warn("Malformated JSON received: " + message.getData()); } catch (JsonMappingException e) { log.warn("Mapping JSON received: " + message.getData()); } catch (IOException e) { log.warn("IO Exception: " + message.getData()); } } else if (data.length == 1) { sendPlain("6:::" + data[0]); } break; case IOMessage.TYPE_ERROR: try { findCallback(message).onError(new SocketIOException(message.getData())); } catch (SocketIOException e) { error(e); } if (message.getData().endsWith("+0")) { // We are advised to disconnect cleanup(); } break; case IOMessage.TYPE_NOOP: break; default: log.warn("Unkown type received" + message.getType()); break; } }