/**
   * Handle the first request for receiving messages on a SockJS HTTP transport based session.
   *
   * <p>Long polling-based transports (e.g. "xhr", "jsonp") complete the request after writing the
   * open frame. Streaming-based transports ("xhr_streaming", "eventsource", and "htmlfile") leave
   * the response open longer for further streaming of message frames but will also close it
   * eventually after some amount of data has been sent.
   *
   * @param request the current request
   * @param response the current response
   * @param frameFormat the transport-specific SocksJS frame format to use
   */
  public void handleInitialRequest(
      ServerHttpRequest request, ServerHttpResponse response, SockJsFrameFormat frameFormat)
      throws SockJsException {

    this.uri = request.getURI();
    this.handshakeHeaders = request.getHeaders();
    this.principal = request.getPrincipal();
    this.localAddress = request.getLocalAddress();
    this.remoteAddress = request.getRemoteAddress();

    this.response = response;
    this.frameFormat = frameFormat;
    this.asyncRequestControl = request.getAsyncRequestControl(response);

    synchronized (this.responseLock) {
      try {
        // Let "our" handler know before sending the open frame to the remote handler
        delegateConnectionEstablished();
        writePrelude(request, response);
        writeFrame(SockJsFrame.openFrame());
        if (isStreaming() && !isClosed()) {
          startAsyncRequest();
        }
      } catch (Throwable ex) {
        tryCloseWithSockJsTransportError(ex, CloseStatus.SERVER_ERROR);
        throw new SockJsTransportFailureException("Failed to open session", getId(), ex);
      }
    }
  }
  @Override
  protected void handleRequestInternal(
      ServerHttpRequest request, ServerHttpResponse response, boolean initialRequest)
      throws IOException {

    byte[] prelude = getPrelude(request);
    Assert.notNull(prelude);
    response.getBody().write(prelude);
    response.flush();

    if (initialRequest) {
      writeFrame(SockJsFrame.openFrame());
    }
    flushCache();
  }