/** * @param sendConnectionPreface true to send connection preface frames. This should always be true * except for in tests that don't check for a connection preface. */ void start(boolean sendConnectionPreface) throws IOException { if (sendConnectionPreface) { frameWriter.connectionPreface(); frameWriter.settings(okHttpSettings); int windowSize = okHttpSettings.getInitialWindowSize(Settings.DEFAULT_INITIAL_WINDOW_SIZE); if (windowSize != Settings.DEFAULT_INITIAL_WINDOW_SIZE) { frameWriter.windowUpdate(0, windowSize - Settings.DEFAULT_INITIAL_WINDOW_SIZE); } } new Thread(readerRunnable).start(); // Not a daemon thread. }
private FramedConnection(Builder builder) throws IOException { protocol = builder.protocol; pushObserver = builder.pushObserver; client = builder.client; listener = builder.listener; // http://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-5.1.1 nextStreamId = builder.client ? 1 : 2; if (builder.client && protocol == Protocol.HTTP_2) { nextStreamId += 2; // In HTTP/2, 1 on client is reserved for Upgrade. } nextPingId = builder.client ? 1 : 2; // Flow control was designed more for servers, or proxies than edge clients. // If we are a client, set the flow control window to 16MiB. This avoids // thrashing window updates every 64KiB, yet small enough to avoid blowing // up the heap. if (builder.client) { okHttpSettings.set(Settings.INITIAL_WINDOW_SIZE, 0, OKHTTP_CLIENT_WINDOW_SIZE); } hostname = builder.hostname; if (protocol == Protocol.HTTP_2) { variant = new Http2(); // Like newSingleThreadExecutor, except lazy creates the thread. pushExecutor = new ThreadPoolExecutor( 0, 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), Util.threadFactory(Util.format("OkHttp %s Push Observer", hostname), true)); // 1 less than SPDY http://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-6.9.2 peerSettings.set(Settings.INITIAL_WINDOW_SIZE, 0, 65535); peerSettings.set(Settings.MAX_FRAME_SIZE, 0, Http2.INITIAL_MAX_FRAME_SIZE); } else if (protocol == Protocol.SPDY_3) { variant = new Spdy3(); pushExecutor = null; } else { throw new AssertionError(protocol); } bytesLeftInWriteWindow = peerSettings.getInitialWindowSize(DEFAULT_INITIAL_WINDOW_SIZE); socket = builder.socket; frameWriter = variant.newWriter(builder.sink, client); readerRunnable = new Reader(variant.newReader(builder.source, client)); }