/**
   * Create a TransportHandlingSockJsService with given {@link TransportHandler handler} types.
   *
   * @param scheduler a task scheduler for heart-beat messages and removing timed-out sessions; the
   *     provided TaskScheduler should be declared as a Spring bean to ensure it gets initialized at
   *     start-up and shuts down when the application stops
   * @param handlers one or more {@link TransportHandler} implementations to use
   */
  public TransportHandlingSockJsService(
      TaskScheduler scheduler, Collection<TransportHandler> handlers) {
    super(scheduler);

    if (CollectionUtils.isEmpty(handlers)) {
      logger.warn("No transport handlers specified for TransportHandlingSockJsService");
    } else {
      for (TransportHandler handler : handlers) {
        handler.initialize(this);
        this.handlers.put(handler.getTransportType(), handler);
      }
    }

    if (jackson2Present) {
      this.messageCodec = new Jackson2SockJsMessageCodec();
    }
  }
  @Override
  protected void handleTransportRequest(
      ServerHttpRequest request,
      ServerHttpResponse response,
      WebSocketHandler handler,
      String sessionId,
      String transport)
      throws SockJsException {

    TransportType transportType = TransportType.fromValue(transport);
    if (transportType == null) {
      logger.error("Unknown transport type for " + request.getURI());
      response.setStatusCode(HttpStatus.NOT_FOUND);
      return;
    }

    TransportHandler transportHandler = this.handlers.get(transportType);
    if (transportHandler == null) {
      logger.error("No TransportHandler for " + request.getURI());
      response.setStatusCode(HttpStatus.NOT_FOUND);
      return;
    }

    HttpMethod supportedMethod = transportType.getHttpMethod();
    if (!supportedMethod.equals(request.getMethod())) {
      if (HttpMethod.OPTIONS.equals(request.getMethod()) && transportType.supportsCors()) {
        if (checkAndAddCorsHeaders(request, response, HttpMethod.OPTIONS, supportedMethod)) {
          response.setStatusCode(HttpStatus.NO_CONTENT);
          addCacheHeaders(response);
        }
      } else if (transportType.supportsCors()) {
        sendMethodNotAllowed(response, supportedMethod, HttpMethod.OPTIONS);
      } else {
        sendMethodNotAllowed(response, supportedMethod);
      }
      return;
    }

    HandshakeInterceptorChain chain = new HandshakeInterceptorChain(this.interceptors, handler);
    SockJsException failure = null;

    try {
      SockJsSession session = this.sessions.get(sessionId);
      if (session == null) {
        if (transportHandler instanceof SockJsSessionFactory) {
          Map<String, Object> attributes = new HashMap<String, Object>();
          if (!chain.applyBeforeHandshake(request, response, attributes)) {
            return;
          }
          SockJsSessionFactory sessionFactory = (SockJsSessionFactory) transportHandler;
          session = createSockJsSession(sessionId, sessionFactory, handler, attributes);
        } else {
          response.setStatusCode(HttpStatus.NOT_FOUND);
          if (logger.isDebugEnabled()) {
            logger.debug(
                "Session not found, sessionId="
                    + sessionId
                    + ". The session may have been closed "
                    + "(e.g. missed heart-beat) while a message was coming in.");
          }
          return;
        }
      }

      if (transportType.sendsNoCacheInstruction()) {
        addNoCacheHeaders(response);
      }

      if (transportType.supportsCors()) {
        if (!checkAndAddCorsHeaders(request, response)) {
          return;
        }
      }

      transportHandler.handleRequest(request, response, handler, session);
      chain.applyAfterHandshake(request, response, null);
    } catch (SockJsException ex) {
      failure = ex;
    } catch (Throwable ex) {
      failure =
          new SockJsException("Uncaught failure for request " + request.getURI(), sessionId, ex);
    } finally {
      if (failure != null) {
        chain.applyAfterHandshake(request, response, failure);
        throw failure;
      }
    }
  }
  @Override
  public void run() {
    try {
      String end = "\r\n";
      String twoHyphens = "--";
      String boundary = "*****++++++************++++++++++++";
      URL url = new URL(ApplicationConfig.UploadMessageAttachments);
      HttpURLConnection connection = (HttpURLConnection) url.openConnection();
      connection.setConnectTimeout(2000);
      connection.setDoInput(true);
      connection.setDoOutput(true);
      connection.setUseCaches(false);
      connection.setRequestMethod("POST");
      connection.setRequestProperty("Connection", "Keep-Alive");
      connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
      DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());

      dataOutputStream.writeBytes(twoHyphens + boundary + end);
      dataOutputStream.writeBytes(
          "Content-Disposition: form-data; name=\"txtFrom\""
              + end
              + end
              + chatContent.get(0)
              + end);
      dataOutputStream.writeBytes(twoHyphens + boundary + end);
      dataOutputStream.writeBytes(
          "Content-Disposition: form-data; name=\"txtTo\"" + end + end + chatContent.get(1) + end);
      dataOutputStream.writeBytes(twoHyphens + boundary + end);
      dataOutputStream.writeBytes(
          "Content-Disposition: form-data; name=\"txtType\""
              + end
              + end
              + chatContent.get(2)
              + end);
      dataOutputStream.writeBytes(twoHyphens + boundary + end);
      dataOutputStream.writeBytes(
          "Content-Disposition: form-data; name=\"txtTile\""
              + end
              + end
              + URLEncoder.encode(chatContent.get(3), "UTF-8")
              + end);
      dataOutputStream.writeBytes(twoHyphens + boundary + end);
      dataOutputStream.writeBytes(
          "Content-Disposition: form-data; name=\"extension\""
              + end
              + end
              + chatContent.get(4)
              + end);
      dataOutputStream.writeBytes(twoHyphens + boundary + end);
      dataOutputStream.writeBytes(
          "Content-Disposition: form-data; name=\"FileUpload1\";filename=\""
              + URLEncoder.encode(chatContent.get(5), "UTF-8")
              + "\""
              + end);
      dataOutputStream.writeBytes(end);

      int totalLength = uploadInputStream.available();
      int bufferSize = 1024;
      byte[] buffer = new byte[bufferSize];
      int uploaded = 0;
      int length = -1;
      while ((length = uploadInputStream.read(buffer)) != -1) {
        if (isCanceled) {
          dataOutputStream.flush();
          dataOutputStream.close();
          break;
        }
        dataOutputStream.write(buffer, 0, length);
        uploaded += length;
        Message message = new Message();
        message.what = UpdateProgressMessage;
        int percent = (uploaded * 100) / totalLength;
        // Wait server process file
        if (percent == 100) {
          percent = 99;
        }
        message.obj = percent;
        transportHandler.sendMessage(message);
      }
      if (!isCanceled) {
        dataOutputStream.writeBytes(end);
        dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + end);
        uploadInputStream.close();
        dataOutputStream.flush();
        dataOutputStream.close();
        if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
          Message message = new Message();
          message.what = UpdateProgressMessage;
          message.obj = 100;
          transportHandler.sendMessage(message);
          if (mUploadListener != null) {
            String fileName =
                chatContent.get(0)
                    + "-"
                    + chatContent.get(1)
                    + "-"
                    + chatContent.get(2)
                    + "-"
                    + chatContent.get(3)
                    + "."
                    + chatContent.get(4);
            mUploadListener.onUploadComplete(fileName);
          }
          transportHandler.sendEmptyMessage(TransportComplete);
        } else {
          transportHandler.sendEmptyMessage(TransportFailed);
        }
      }
    } catch (MalformedURLException e) {
      e.printStackTrace();
    } catch (SocketTimeoutException e) {
      transportHandler.sendEmptyMessage(ConnectTimeOut);
    } catch (ProtocolException e) {
      e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }