Hi,

Yes. my bad. I just remove the commit.


Arturo


On Tue, Dec 23, 2025 at 10:40 AM Oleg Kalnichevski <[email protected]> wrote:

> Why are those changes in the 5.6 and not in 5.7? SSE module in is master
> and is not in the 5.6.x branch.
>
> Oleg
>
>
> https://github.com/apache/httpcomponents-website/tree/master/src/site/markdown/httpcomponents-client-5.7.x
>
> On 12/23/2025 10:10, [email protected] wrote:
> > This is an automated email from the ASF dual-hosted git repository.
> >
> > abernal pushed a commit to branch master
> > in repository
> https://gitbox.apache.org/repos/asf/httpcomponents-website.git
> >
> >
> > The following commit(s) were added to refs/heads/master by this push:
> >       new bb99baa  Add HttpClient SSE module docs (overview, guide,
> examples, javadocs links)
> > bb99baa is described below
> >
> > commit bb99baa372e97666bb4624452afef77cba20f8fa
> > Author: Arturo Bernal <[email protected]>
> > AuthorDate: Tue Dec 23 10:10:10 2025 +0100
> >
> >      Add HttpClient SSE module docs (overview, guide, examples, javadocs
> links)
> > ---
> >   .../httpcomponents-client-5.6.x/examples-sse.md    | 191
> ++++++++++++++++++++
> >   .../markdown/httpcomponents-client-5.6.x/index.md  |   6 +
> >   .../markdown/httpcomponents-client-5.6.x/sse.md    | 192
> +++++++++++++++++++++
> >   3 files changed, 389 insertions(+)
> >
> > diff --git
> a/src/site/markdown/httpcomponents-client-5.6.x/examples-sse.md
> b/src/site/markdown/httpcomponents-client-5.6.x/examples-sse.md
> > new file mode 100644
> > index 0000000..6977ca6
> > --- /dev/null
> > +++ b/src/site/markdown/httpcomponents-client-5.6.x/examples-sse.md
> > @@ -0,0 +1,191 @@
> > +<!--
> > +    Licensed to the Apache Software Foundation (ASF) under one
> > +    or more contributor license agreements.  See the NOTICE file
> > +    distributed with this work for additional information
> > +    regarding copyright ownership.  The ASF licenses this file
> > +    to you under the Apache License, Version 2.0 (the
> > +    "License"); you may not use this file except in compliance
> > +    with the License.  You may obtain a copy of the License at
> > +
> > +      http://www.apache.org/licenses/LICENSE-2.0
> > +
> > +    Unless required by applicable law or agreed to in writing,
> > +    software distributed under the License is distributed on an
> > +    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > +    KIND, either express or implied.  See the License for the
> > +    specific language governing permissions and limitations
> > +    under the License.
> > +-->
> > +
> > +HttpClient SSE examples
> > +=======================
> > +
> > +This page shows complete examples for the optional SSE module
> (`httpclient5-sse`).
> > +
> > +Example 1: public stream (Wikimedia recent changes)
> > +---------------------------------------------------
> > +
> > +This example is based on
> `org.apache.hc.client5.http.sse.example.ClientSseExample` from the
> > +`httpclient5-sse` module tests.
> > +
> > +It demonstrates:
> > +
> > +- Custom async client with HTTP/2 negotiation and stream multiplexing.
> > +- Dedicated scheduler for reconnect backoff.
> > +- `SseParser.BYTE` for reduced allocations.
> > +- A simple listener with lifecycle handling.
> > +
> > +```java
> > +import java.net.URI;
> > +import java.util.HashMap;
> > +import java.util.Locale;
> > +import java.util.Map;
> > +import java.util.concurrent.CountDownLatch;
> > +import java.util.concurrent.Executor;
> > +import java.util.concurrent.ScheduledThreadPoolExecutor;
> > +
> > +import org.apache.hc.client5.http.config.TlsConfig;
> > +import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
> > +import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
> > +import
> org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
> > +import
> org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
> > +import org.apache.hc.client5.http.sse.EventSource;
> > +import org.apache.hc.client5.http.sse.EventSourceConfig;
> > +import org.apache.hc.client5.http.sse.EventSourceListener;
> > +import org.apache.hc.client5.http.sse.SseExecutor;
> > +import org.apache.hc.client5.http.sse.impl.ExponentialJitterBackoff;
> > +import org.apache.hc.client5.http.sse.impl.SseParser;
> > +import org.apache.hc.core5.concurrent.DefaultThreadFactory;
> > +import org.apache.hc.core5.http2.HttpVersionPolicy;
> > +import org.apache.hc.core5.http2.config.H2Config;
> > +import org.apache.hc.core5.reactor.IOReactorConfig;
> > +import org.apache.hc.core5.util.TimeValue;
> > +
> > +public final class ClientSseExample {
> > +
> > +    public static void main(final String[] args) throws Exception {
> > +        final URI uri = URI.create(args.length > 0
> > +                ? args[0]
> > +                : "https://stream.wikimedia.org/v2/stream/recentchange
> ");
> > +
> > +        final IOReactorConfig ioCfg = IOReactorConfig.custom()
> > +                .setIoThreadCount(Math.max(2,
> Runtime.getRuntime().availableProcessors()))
> > +                .setSoKeepAlive(true)
> > +                .setTcpNoDelay(true)
> > +                .build();
> > +
> > +        final PoolingAsyncClientConnectionManager connMgr =
> > +                PoolingAsyncClientConnectionManagerBuilder.create()
> > +                        .useSystemProperties()
> > +                        .setMessageMultiplexing(true)
> > +                        .setMaxConnPerRoute(32)
> > +                        .setMaxConnTotal(256)
> > +                        .setDefaultTlsConfig(
> > +                                TlsConfig.custom()
> > +
> .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
> > +                                        .build())
> > +                        .build();
> > +
> > +        final CloseableHttpAsyncClient httpClient =
> HttpAsyncClientBuilder.create()
> > +                .setIOReactorConfig(ioCfg)
> > +                .setConnectionManager(connMgr)
> > +                .setH2Config(H2Config.custom()
> > +                        .setPushEnabled(false)
> > +                        .setMaxConcurrentStreams(256)
> > +                        .build())
> > +                .useSystemProperties()
> > +                .evictExpiredConnections()
> > +                .evictIdleConnections(TimeValue.ofMinutes(1))
> > +                .build();
> > +
> > +        final ScheduledThreadPoolExecutor scheduler =
> > +                new ScheduledThreadPoolExecutor(4, new
> DefaultThreadFactory("sse-backoff", true));
> > +        scheduler.setRemoveOnCancelPolicy(true);
> > +
> > +        final Executor callbacks = Runnable::run;
> > +
> > +        final EventSourceConfig cfg = EventSourceConfig.builder()
> > +                .backoff(new ExponentialJitterBackoff(500L, 30_000L,
> 2.0, 250L))
> > +                .maxReconnects(-1)
> > +                .build();
> > +
> > +        final Map<String, String> defaultHeaders = new HashMap<>();
> > +        defaultHeaders.put("User-Agent", "Apache-HttpClient-SSE/5.x");
> > +        defaultHeaders.put("Accept-Language", "en");
> > +
> > +        final SseExecutor exec = SseExecutor.custom()
> > +                .setHttpClient(httpClient)
> > +                .setScheduler(scheduler)
> > +                .setCallbackExecutor(callbacks)
> > +                .setEventSourceConfig(cfg)
> > +                .setDefaultHeaders(defaultHeaders)
> > +                .setParserStrategy(SseParser.BYTE)
> > +                .build();
> > +
> > +        final CountDownLatch done = new CountDownLatch(1);
> > +
> > +        final EventSourceListener listener = new EventSourceListener() {
> > +            @Override
> > +            public void onOpen() {
> > +                System.out.println("[SSE] open: " + uri);
> > +            }
> > +
> > +            @Override
> > +            public void onEvent(final String id, final String type,
> final String data) {
> > +                final String shortData = data.length() > 120 ?
> data.substring(0, 120) + "…" : data;
> > +                System.out.printf(Locale.ROOT, "[SSE] %s id=%s %s%n",
> > +                        type != null ? type : "message", id, shortData);
> > +            }
> > +
> > +            @Override
> > +            public void onFailure(final Throwable t, final boolean
> willReconnect) {
> > +                System.err.println("[SSE] failure: " + t + "
> willReconnect=" + willReconnect);
> > +                if (!willReconnect) {
> > +                    done.countDown();
> > +                }
> > +            }
> > +
> > +            @Override
> > +            public void onClosed() {
> > +                System.out.println("[SSE] closed");
> > +                done.countDown();
> > +            }
> > +        };
> > +
> > +        final EventSource es = exec.open(uri, listener);
> > +
> > +        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
> > +            try {
> > +                es.cancel();
> > +            } catch (final Exception ignore) {
> > +            }
> > +            try {
> > +                exec.close();
> > +            } catch (final Exception ignore) {
> > +            }
> > +            try {
> > +                scheduler.shutdownNow();
> > +            } catch (final Exception ignore) {
> > +            }
> > +        }, "sse-shutdown"));
> > +
> > +        es.start();
> > +        done.await();
> > +
> > +        es.cancel();
> > +        exec.close();
> > +        scheduler.shutdownNow();
> > +    }
> > +}
> > +```
> > +
> > +Example 2: perf harness
> > +----------------------
> > +
> > +The `httpclient5-sse` tests also include a small performance harness:
> > +
> > +- `org.apache.hc.client5.http.sse.example.performance.SsePerfServer` –
> local SSE server with configurable rate/payload.
> > +- `org.apache.hc.client5.http.sse.example.performance.SsePerfClient` –
> many connections, ramp-up batching, simple
> > +  latency histogram.
> > +
> > +Those classes are intended for development / benchmarking (not as a
> public API).
> > diff --git a/src/site/markdown/httpcomponents-client-5.6.x/index.md
> b/src/site/markdown/httpcomponents-client-5.6.x/index.md
> > index dd05275..311d5e1 100644
> > --- a/src/site/markdown/httpcomponents-client-5.6.x/index.md
> > +++ b/src/site/markdown/httpcomponents-client-5.6.x/index.md
> > @@ -53,6 +53,8 @@ Documentation
> >      * [Observation](observation.md)
> >      * [SCRAM-SHA-256](scram-sha-256.md)
> >      * [SPKI pinning TLS strategy](spki-pinning.md)
> > +   * [Server-Sent Events (SSE)](sse.md)
> > +
> >
> >   6. Examples demonstrating some common as well as more complex use cases
> >
> > @@ -60,6 +62,7 @@ Documentation
> >      * [HttpClient (async APIs)](examples-async.md)
> >      * [HttpClient (reactive APIs)](examples-reactive.md)
> >      * [HttpClient (observation APIs)](examples-observation.md)
> > +   * [HttpClient (SSE APIs)](examples-sse.md)
> >
> >   1. Javadocs
> >
> > @@ -67,6 +70,7 @@ Documentation
> >      * [HC Fluent](./current/httpclient5-fluent/apidocs/)
> >      * [HttpClient Cache](./current/httpclient5-cache/apidocs/)
> >      * [HttpClient
> Observation](./current/httpclient5-observation/apidocs/)
> > +   * [HttpClient SSE](./current/httpclient5-sse/apidocs/)
> >
> >   1. API compatibility reports
> >
> > @@ -99,6 +103,8 @@ Features
> >   - Optional Server-Sent Events (SSE) module for consuming long-lived
> event
> >     streams over HTTP/1.1 and HTTP/2 using the async transport.
> >   - Source code is freely available under the Apache License.
> > +- Optional Server-Sent Events (SSE) module for consuming long-lived
> event
> > +  streams over HTTP/1.1 and HTTP/2 using the async transport.
> >
> >
> >   Standards Compliance
> > diff --git a/src/site/markdown/httpcomponents-client-5.6.x/sse.md
> b/src/site/markdown/httpcomponents-client-5.6.x/sse.md
> > new file mode 100644
> > index 0000000..748770d
> > --- /dev/null
> > +++ b/src/site/markdown/httpcomponents-client-5.6.x/sse.md
> > @@ -0,0 +1,192 @@
> > +<!--
> > +    Licensed to the Apache Software Foundation (ASF) under one
> > +    or more contributor license agreements.  See the NOTICE file
> > +    distributed with this work for additional information
> > +    regarding copyright ownership.  The ASF licenses this file
> > +    to you under the Apache License, Version 2.0 (the
> > +    "License"); you may not use this file except in compliance
> > +    with the License.  You may obtain a copy of the License at
> > +
> > +      http://www.apache.org/licenses/LICENSE-2.0
> > +
> > +    Unless required by applicable law or agreed to in writing,
> > +    software distributed under the License is distributed on an
> > +    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> > +    KIND, either express or implied.  See the License for the
> > +    specific language governing permissions and limitations
> > +    under the License.
> > +-->
> > +
> > +Server-Sent Events (SSE)
> > +========================
> > +
> > +Server-Sent Events (SSE) is a simple, server → client streaming
> protocol built on top of HTTP. The server keeps an
> > +HTTP response open and sends events as lines in the `text/event-stream`
> format.
> > +
> > +HttpClient provides an optional SSE module (`httpclient5-sse`) that
> consumes long-lived event streams over HTTP/1.1 and
> > +HTTP/2 using the async transport.
> > +
> > +Requirements
> > +------------
> > +
> > +- Java 8+
> > +- Apache HttpClient 5.7+ (the SSE module is `@since 5.7`)
> > +
> > +Dependency
> > +----------
> > +
> > +Maven:
> > +
> > +```xml
> > +<dependency>
> > +  <groupId>org.apache.httpcomponents.client5</groupId>
> > +  <artifactId>httpclient5-sse</artifactId>
> > +  <version>${httpclient.version}</version>
> > +</dependency>
> > +```
> > +
> > +Gradle:
> > +
> > +```gradle
> >
> +implementation("org.apache.httpcomponents.client5:httpclient5-sse:${httpclientVersion}")
> > +```
> > +
> > +Quick start
> > +-----------
> > +
> > +The SSE API is intentionally small:
> > +
> > +- `SseExecutor` is the entry point.
> > +- `EventSource` represents a single SSE stream.
> > +- `EventSourceListener` receives events and lifecycle callbacks.
> > +
> > +Minimal example (shared async client):
> > +
> > +```java
> > +import java.net.URI;
> > +
> > +import org.apache.hc.client5.http.sse.EventSource;
> > +import org.apache.hc.client5.http.sse.EventSourceListener;
> > +import org.apache.hc.client5.http.sse.SseExecutor;
> > +
> > +public final class MinimalSse {
> > +
> > +    public static void main(final String[] args) throws Exception {
> > +        final URI uri = URI.create("
> https://stream.wikimedia.org/v2/stream/recentchange";);
> > +
> > +        final SseExecutor exec = SseExecutor.newInstance();
> > +        final EventSource es = exec.open(uri, new EventSourceListener()
> {
> > +            @Override
> > +            public void onOpen() {
> > +                System.out.println("[SSE] open");
> > +            }
> > +
> > +            @Override
> > +            public void onEvent(final String id, final String type,
> final String data) {
> > +                System.out.println("[SSE] " + (type != null ? type :
> "message") + ": " + data);
> > +            }
> > +
> > +            @Override
> > +            public void onFailure(final Throwable t, final boolean
> willReconnect) {
> > +                System.err.println("[SSE] failure=" + t + "
> willReconnect=" + willReconnect);
> > +            }
> > +
> > +            @Override
> > +            public void onClosed() {
> > +                System.out.println("[SSE] closed");
> > +            }
> > +        });
> > +
> > +        es.start();
> > +
> > +        // ... do other work ...
> > +
> > +        // Stop the stream (no further reconnects) when you are done.
> > +        es.cancel();
> > +
> > +        // When using the shared client, exec.close() is a no-op.
> > +        // Call SseExecutor.closeSharedClient() if you want to
> explicitly shut it down.
> > +    }
> > +}
> > +```
> > +
> > +Configuration
> > +-------------
> > +
> > +Reconnect / backoff
> > +~~~~~~~~~~~~~~~~~~~
> > +
> > +Reconnects are controlled by `EventSourceConfig` and `BackoffStrategy`.
> > +
> > +- `maxReconnects = -1` means “try forever”.
> > +- The default backoff is `ExponentialJitterBackoff` and it honors
> server hints:
> > +  - the SSE `retry:` field (milliseconds)
> > +  - the HTTP `Retry-After` header
> > +
> > +Example:
> > +
> > +```java
> > +import org.apache.hc.client5.http.sse.EventSourceConfig;
> > +import org.apache.hc.client5.http.sse.impl.ExponentialJitterBackoff;
> > +
> > +final EventSourceConfig cfg = EventSourceConfig.builder()
> > +        .backoff(new ExponentialJitterBackoff(500L, 30_000L, 2.0, 250L))
> > +        .maxReconnects(-1)
> > +        .build();
> > +```
> > +
> > +Threading
> > +~~~~~~~~~
> > +
> > +Listener callbacks must be non-blocking.
> > +
> > +- If you do heavy work in `onEvent(...)`, provide a callback executor
> so the I/O threads stay responsive.
> > +- Reconnect scheduling can use an application scheduler (recommended
> for large fan-out).
> > +
> > +The builder makes those defaults explicit:
> > +
> > +```java
> > +import java.util.concurrent.Executor;
> > +import java.util.concurrent.ScheduledExecutorService;
> > +
> > +import org.apache.hc.client5.http.sse.SseExecutor;
> > +
> > +final ScheduledExecutorService scheduler = /* your scheduler */;
> > +final Executor callbacks = /* your callback executor */;
> > +
> > +final SseExecutor exec = SseExecutor.custom()
> > +        .setScheduler(scheduler)
> > +        .setCallbackExecutor(callbacks)
> > +        .build();
> > +```
> > +
> > +HTTP/2 multiplexing
> > +~~~~~~~~~~~~~~~~~~~
> > +
> > +SSE works over HTTP/1.1 and HTTP/2.
> > +
> > +- The default shared client created by `SseExecutor.newInstance()` uses
> a pooling async connection manager with message
> > +  multiplexing enabled.
> > +- If you provide your own async client, enable message multiplexing if
> you plan to run many streams over a small number
> > +  of HTTP/2 connections.
> > +
> > +Request headers and resumption
> > +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > +
> > +- The implementation always sends `Accept: text/event-stream`.
> > +- The most recent non-null event id is tracked and used as
> `Last-Event-ID` on reconnect.
> > +- You can set and remove headers on the `EventSource` to affect
> subsequent reconnects.
> > +
> > +```java
> > +es.setHeader("Authorization", "Bearer ...");
> > +es.removeHeader("Authorization");
> > +
> > +final String last = es.lastEventId();
> > +es.setLastEventId(last); // override / resume manually
> > +```
> > +
> > +See also
> > +--------
> > +
> > +- [SSE examples](examples-sse.md)
> > +- Module javadocs: `./current/httpclient5-sse/apidocs/`
> >
>
>

Reply via email to