예제 #1
0
  /**
   * Creates a new {@link IOAcknowledge} instance which sends its arguments back to the server.
   *
   * @param message the message
   * @return an {@link IOAcknowledge} instance, may be <code>null</code> if server doesn't request
   *     one.
   */
  private IOAcknowledge remoteAcknowledge(IOMessage message) {

    String _id = message.getId();
    if (_id.equals("")) {
      return null;
    } else if (!_id.endsWith("+")) {
      _id = _id + "+";
    }
    final String id = _id;
    final String endPoint = message.getEndpoint();
    return new IOAcknowledge() {

      @Override
      public void ack(Object... args) {

        String jsonString = null;
        try {
          jsonString = objectMapper.writeValueAsString(args);
        } catch (Exception e) {
          error(
              new SocketIOException(
                  "You can only put values in IOAcknowledge.ack() which can be serialized", e));
        }
        IOMessage ackMsg = new IOMessage(IOMessage.TYPE_ACK, endPoint, id + jsonString);
        sendPlain(ackMsg.toString());
      }
    };
  }
예제 #2
0
  /**
   * finds the corresponding callback object to an incoming message. Returns a dummy callback if no
   * corresponding callback can be found
   *
   * @param message the message
   * @return the iO callback
   * @throws SocketIOException
   */
  private IOCallback findCallback(IOMessage message) throws SocketIOException {

    if ("".equals(message.getEndpoint())) {
      return this;
    }
    SocketIO socket = sockets.get(message.getEndpoint());
    if (socket == null) {
      throw new SocketIOException("Cannot find socket for '" + message.getEndpoint() + "'");
    }
    return socket.getCallback();
  }
예제 #3
0
  /**
   * Connects a socket to the IOConnection.
   *
   * @param socket the socket to be connected
   * @return true, if successfully registered on this transport, otherwise false.
   */
  public boolean register(SocketIO socket) {

    String namespace = socket.getNamespace();
    if (sockets.containsKey(namespace)) {
      return false;
    }
    sockets.put(namespace, socket);
    socket.setHeaders(headers);
    IOMessage connect = new IOMessage(IOMessage.TYPE_CONNECT, socket.getNamespace(), "");
    sendPlain(connect.toString());
    return true;
  }
예제 #4
0
  /**
   * adds an {@link IOAcknowledge} to an {@link IOMessage}.
   *
   * @param message the {@link IOMessage}
   * @param ack the {@link IOAcknowledge}
   */
  private void synthesizeAck(IOMessage message, IOAcknowledge ack) {

    if (ack != null) {
      int id = nextId++;
      acknowledge.put(id, ack);
      message.setId(id + "+");
    }
  }
예제 #5
0
  /**
   * emits an event from {@link SocketIO} to the {@link IOTransport}.
   *
   * @param socket the socket
   * @param event the event
   * @param ack acknowledge package which can be called from the server
   * @param args the arguments to be send
   */
  public void emit(SocketIO socket, String event, IOAcknowledge ack, Object... args) {

    String jsonString = null;
    try {

      Map<String, Object> map = new HashMap<String, Object>();
      map.put("name", event);
      map.put("args", args);
      jsonString = objectMapper.writeValueAsString(map);

      IOMessage message = new IOMessage(IOMessage.TYPE_EVENT, socket.getNamespace(), jsonString);
      synthesizeAck(message, ack);
      sendPlain(message.toString());

    } catch (Exception e) {
      error(
          new SocketIOException(
              "Error while emitting an event. Make sure you only try to send arguments, which can be serialized into JSON."));
    }
  }
 private void send(String content) throws IOException, JSONException {
   IOMessage msg = new IOMessage(IOMessage.MESSAGE, -1, "", content);
   socket.getWebSocket().send(msg.toString());
 }
예제 #7
0
  /**
   * sends a String message from {@link SocketIO} to the {@link IOTransport}.
   *
   * @param socket the socket
   * @param ack acknowledge package which can be called from the server
   * @param text the text
   */
  public void send(SocketIO socket, IOAcknowledge ack, String text) {

    IOMessage message = new IOMessage(IOMessage.TYPE_MESSAGE, socket.getNamespace(), text);
    synthesizeAck(message, ack);
    sendPlain(message.toString());
  }
예제 #8
0
  /**
   * 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;
    }
  }