#sse

2025-10-22

Пишем чат на Rust

Очередной чат, и к тому же на rust?! Да, yet another. И да, в этой статье не будет каких-то новых откровений системного программирования с написанием своего фреймворка для работы со сетью на уровне драйверов или других испытаний. Этот альманах про мой первый опыт в веб-разработке, который может быть полезен для других новичков, ведь тут мы затронем помимо злосчастного rust такие вещи, как devcontainer, REST API, идентификацию-аутентификацию-авторизацию, WebSockets, SSE, юнит и интеграционные тесты, некоторые паттерны, логирование и прочее.

habr.com/ru/articles/945042/

#rust #вебразработа #фуллстек #sse #websockets #devcontainer #авторизация #чат #rest_api

Wouter Tebbens ⁂Wtebbens@social.coop
2025-10-16

Looking for alternatives to Israel owned or produced brands, probably your local cooperative or other worker-owned Social and Solidarity Economy has many options.

The catalan coop media Jornal.cat compiled an extensive list, and we're happy to see CommonsCloud.coop (in its catalan name: SomNúvol) in it. Besides the free software community, and various platform cooperatives like @sommobilitat @ecotxe and many locally relevant organisations.

jornal.cat/noticia/39316/alter

#BDS #SSE

2025-10-15

SSE + Java + WebFlux = энтерпрайз решение для отправки пушей

В этом посте я расскажу, почему для доставки push-уведомлений в клиентское приложение была выбрана технология Server-Sent Events , и главное, как реализовать масштабируемый SSE сервис на Java + Spring Boot + Webflux, который подойдет для использования не только в небольших проектах, но и в крупных организациях с большим количеством пользователей. Естественно, без подготовки дополнительной инфраструктуры не обойдется.

habr.com/ru/articles/956766/

#java #webflux #sse #spring #микросервисы #энтерпрайз #архитектура #инфраструктура #rabbitmq #redis

Jennifer LeonardLeonard@ecoevo.social
2025-10-08

The Society for the Study of Evolution #SSE is now accepting nominations
for the #Dobzhansky #Prize to recognize the accomplishments and future promise of an outstanding early-career evolutionary biologist in any area of evolutionary biology, on any
taxonomic group/system, using empirical and/or theoretical approaches.

The recipient presents an award talk, receives $5,000 and 3 yr membership

Submissions due Dec 1, 2025: shorturl.at/p70wY

communications@evolutionsociety.org
#Evolution

Alejandro Baezzeab@fosstodon.org
2025-10-03

Another project for #Hypermedia in #python. Hold up! It's a fork of #fasthtml. Using #datastar instead of #htmx. 😅

The difference here is how much datastar use #SSE (#ServerSentEvents). It's EVERYWHERE. Very potent stuff.

Hadn't yet tried datastar, but maybe soon with this. 😁

starhtml.com/

2025-09-26

Datastar links.shikiryu.com/shaare/lDHh Un framework JS qui a l'air sympa et léger pour faire du SSE
#dev #framework #js #sse

Amaury Bouchardamaury@phpc.social
2025-09-20

Ma conférence "Server Sent Events et ZeroMQ"

Mardi dernier (16 septembre), j’ai présenté une conférence au meetup organisé par l’AFUP Paris, sur les Server Sent Events (SSE) et la bibliothèque ZeroMQ.

Retrouvez les slides de la conférence dans l'article en lien.

geek-directeur-technique.com/2
#php #sse #zeromq #afup

Real-Time in Focus: Server-Sent Events in Core Java without Frameworks

Chapter 1 – Introduction

1.1 Motivation: Real-time communication without polling

In modern applications, it is often necessary to provide new information to the client as quickly as possible. Classic polling, i.e. regularly querying a REST endpoint, is inefficient: it generates unnecessary network traffic and puts a load on both server and client, as requests continue even when there is no new data.

Server-sent events (SSE) offer a resource-saving alternative here. Instead of the client constantly sending new requests, it maintains an open HTTP connection over which the server can send messages at any time. This creates a continuous stream of data with minimal overhead.

  1. Chapter 1 – Introduction
    1. 1.1 Motivation: Real-time communication without polling
    2. 1.2 Differentiation from WebSockets and Long Polling
    3. 1.3 Objective of the article
  2. Chapter 2 – The SSE Protocol
    1. 2.1 MIME type text/event-stream
    2. 2.2 Message structure: event:, data:, id: and comments
    3. 2.3 Automatic Reconnect and Event IDs
    4. 2.4 Limitations: UTF-8, Unidirectionality, Proxy Behaviour
  3. Chapter 3 – Minimal REST/SSE Server in Core Java
    1. 3.1 Implementation with HttpServer
    2. 3.2 Sending Events (Text, Comments, IDs)
    3. 3.3 Keep-Alive and Connection Stability
    4. 3.4 Step-by-step implementation – complete minimal example
  4. Chapter 4 – Minimal SSE Client in Core Java
    1. 4.1 Implementation with HttpClient
    2. 4.2 Interpreting Events
    3. 4.3 Behaviour in case of aborting and reconnect
  5. Chapter 5 – Testing and Debugging SSE
    1. 5.1 Using curl and browser EventSource
    2. 5.2 Checking with Java Client
    3. 5.3 Monitoring and logging
  6. Chapter 6 – Application Scenarios and Limitations

1.2 Differentiation from WebSockets and Long Polling

In the context of current communication paradigms, three basic approaches can be distinguished. In so-called long polling, the client initiates a request that the server keeps open as long as possible until new information is available. After this has been transmitted, the connection is closed, whereupon the client immediately opens a new request. Although this method appears to be more efficient than classic polling, it remains resource-intensive due to the frequent reinitialization of the connections.

In contrast, WebSockets establish a full-duplex communication relationship. Here, both client and server can exchange messages continuously and bidirectionally. This model offers high flexibility and performance, but it also introduces increased complexity in implementation and operation, often resulting in oversizing when only server-side push messages are needed.

Server-sent events (SSE) act as an intermediary approach. They establish a standardised, unidirectional data stream from the server to the client via a persistent HTTP connection. The native support of current browsers and the comparatively low implementation effort on the server side make SSE a practical option, especially in scenarios where simplicity and resource conservation are paramount.

Sourcecode is on GitHub
https://github.com/Java-Publications/Blog—Java—Server-Sent-Events-SSE-in-Core-Java-Basics-and-Implementation

1.3 Objective of the article

This article provides a basic introduction to Server-Sent Events (SSE) using Core Java. The focus is on consistent implementation based on the Java Development Kit (JDK), without recourse to external frameworks. The aim is to analyse the specifics of the protocol as well as the minimal implementations on both the server side and the client side in a systematic form and to present them in a comprehensible manner.

In the course of the study, it is illustrated how an elementary REST/SSE server can be constructed in Java, how a client can receive and process event streams using the Java HttpClient, which typical difficulties arise in the context of testing and debugging, and in which application scenarios the use of SSE offers significant added value.

Finally, the position of SSE in the area of tension between polling and WebSocket-based methods is critically classified and the transition to the following, practice-oriented implementation chapters is prepared.

Chapter 2 – The SSE Protocol

2.1 MIME type text/event-stream

The foundation of server-sent events is the dedicated MIME type text/event-stream. As soon as a server declares this Content-Type in the HTTP header, it signals to the client that the subsequent data is to be interpreted as a continuous event stream. In contrast to conventional textual response formats, which are closed after complete transmission, SSE deliberately keeps the connection open persistently. This semantic definition creates the basis for a resource-saving push model that can be integrated into existing HTTP infrastructures without proprietary extensions.

2.2 Message structure: event:, data:, id: and comments

An SSE data stream is organised on a row-based basis. Each message can consist of multiple fields preceded by a keyword and a colon. The most important fields are:

  • event: defines the type of event that the client can handle specifically.
  • data: contains the actual payload. Consecutive data lines summarise multi-line data fields.
  • id: represents an event ID that is used for resumption after disconnections.
  • Comments: start with a colon and are used both for semantic documentation and to maintain keep-alive signals.

The delimitation of individual events is done by a blank line (double line breaks), which completes the semantic unit of a message.

2.3 Automatic Reconnect and Event IDs

A significant advantage of SSE over simpler push mechanisms is the integrated reconnect behaviour. If a connection is unexpectedly interrupted, the client automatically initiates a new connection. Using the Last Event ID HTTP header fields or explicit ID assignments in the data stream, it is possible to continue at the exact point where the data stream was interrupted. This principle reduces data loss and facilitates the implementation of robust, state-preserving communication patterns.

2.4 Limitations: UTF-8, Unidirectionality, Proxy Behaviour

Despite its simplicity, the protocol has inherent limitations. On the one hand, the character encoding is strictly set to UTF-8, which means that binary payloads cannot be transmitted directly. In addition, the direction of communication is limited to server-side messages; a bidirectional interaction requires recourse to alternative methods such as WebSockets. Finally, the behaviour of intermediary network nodes – such as proxies or load balancers – can affect the longevity and stability of open HTTP connections, which deserves special attention in production environments.

Chapter 3 – Minimal REST/SSE Server in Core Java

3.1 Implementation with HttpServer

An elementary SSE server can be implemented in Java using the classes included in the JDK. Of particular note is the com.sun.net.httpserver.HttpServer class, which allows HTTP endpoints to be provided without external dependencies. Such a server can be created with a few lines of code, bound to a port number and extended by handlers that process incoming requests.

A minimal basic framework looks like this:

HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);server.createContext("/events", exchange -> {    exchange.getResponseHeaders().add("Content-Type", "text/event-stream");    exchange.sendResponseHeaders(200, 0);    OutputStream os = exchange.getResponseBody();    //This is where the events will be written later});server.start();

It is crucial to set the content type to text/event-stream and not to close the HTTP connection immediately. This creates the basis for continuously transmitting event data to the client.

3.2 Sending Events (Text, Comments, IDs)

The server-side logic for transmitting messages follows the formats defined in the protocol. A typical message can contain both a data: field with payload and optional metadata. Comments are beneficial for realising keep-alive signals.

A simple example of how to transmit messages:

PrintWriter writer = new PrintWriter(os, true);writer.println("id: 1");writer.println("event: greeting");writer.println("data: Hello client!");writer.println(); End messagewriter.flush();//Comment as a heartbeatwriter.println(": keep-alive");writer.println();writer.flush();

Here, a message is transmitted with ID, event type, and data. The double line break concludes the semantic unit. The comment is to maintain the connection.

3.3 Keep-Alive and Connection Stability

A critical aspect of running SSE servers is ensuring connection stability. HTTP connections can be terminated by inactivity or by restrictive network infrastructures. To avoid this, it is common practice to periodically send comments or blank messages that are ignored by the client but registered as activity by the network. This technique, often referred to as heartbeat or keep-alive, helps keep the connection stable for extended periods of time.

A robust implementation should also ensure that there are no resource leaks when the connection is lost. In particular, this means that OutputStreams must be reliably closed and background threads must be terminated in a controlled manner.

This step-by-step implementation creates a functional SSE server that meets the fundamental protocol requirements. In the following chapters, this is built on by developing a corresponding client and examining the robustness of the communication.

3.4 Step-by-step implementation – complete minimal example

In the following, an executable minimal server is set up in clearly defined steps. The implementation uses only the JDK (no external dependencies) and relies on com.sun.net.httpserver.HttpServer.

Create and start the server

package com.svenruppert.sse;import com.sun.net.httpserver.HttpServer;import com.svenruppert.dependencies.core.logger.HasLogger;import java.io.*;import java.net.InetSocketAddress;import static java.nio.charset.StandardCharsets.UTF_8;public class SseServer    implements HasLogger {  protected static final String PATH_SSE = "/sse";  private volatile boolean sendMessages = false;  private volatile boolean shutdownMessage = false;  // Reference so we can properly stop the server from the CLI  private HttpServer server;  public void start()      throws Exception {    int port = 8080;    this.server = HttpServer.create(new InetSocketAddress(port), 0);    // Background thread for CLI control (start | stop | shutdown)    Thread cli = new Thread(() -> {      try (BufferedReader console = new BufferedReader(new InputStreamReader(System.in))) {        String line;        while ((line = console.readLine()) != null) {          String cmd = line.trim().toLowerCase();          switch (cmd) {            case "start" -> cmdStart();            case "stop" -> cmdStop();            case "shutdown" -> cmdShutdown();            default -> logger().info("Unknown command: {} (allowed: start | stop | shutdown)", cmd);          }        }      } catch (IOException ioe) {        logger().warn("CLI control terminated: {}", ioe.getMessage());      }    }, "cli-control");    cli.setDaemon(true);    cli.start();    server.createContext(PATH_SSE, exchange -> {      if (!"GET".equalsIgnoreCase(exchange.getRequestMethod())) {        exchange.sendResponseHeaders(405, -1);        return;      }      exchange.getResponseHeaders().add("Content-Type", "text/event-stream; charset=utf-8");      exchange.getResponseHeaders().add("Cache-Control", "no-cache");      exchange.getResponseHeaders().add("Connection", "keep-alive");      exchange.sendResponseHeaders(200, 0);      try (OutputStream os = exchange.getResponseBody();           OutputStreamWriter osw = new OutputStreamWriter(os, UTF_8);           BufferedWriter bw = new BufferedWriter(osw);           PrintWriter out = new PrintWriter(bw, true)) {        long id = 0;        while (!shutdownMessage) {          if (sendMessages) {            id++;            String data = "tick @" + System.currentTimeMillis();            writeEvent(out, "tick", data, Long.toString(id));          } else {            heartbeat(out);          }          Thread.sleep(1000);        }        // Optional: send farewell event before shutting down        writeEvent(out, "shutdown", "Server is shutting down", Long.toString(++id));      } catch (IOException | InterruptedException ioe) {        logger().warn("SSE client disconnected: {}", ioe.getMessage());      } finally {        logger().info("SSE stream closed");      }    });    server.start();    logger().info("SSE server running at http://localhost:{}/sse", port);    Runtime.getRuntime().addShutdownHook(new Thread(() -> {      logger().info("Stopping server …");      if (server != null) {        server.stop(0);      }    }));  }  private void cmdShutdown() {    logger().info("Shutdown command received – 'shutdown' event will be sent …");    shutdownMessage = true; // signals all active handlers to send a shutdown event    try {      // Grace period so handlers can still execute writeEvent(..., "shutdown", ...) + flush      Thread.sleep(1200);    } catch (InterruptedException ie) {      Thread.currentThread().interrupt();    }    try {      if (server != null) {        server.stop(0); // stop HTTP server afterwards      }    } catch (Exception e) {      logger().warn("Error while stopping: {}", e.getMessage());    }    logger().info("Application is shutting down.");    System.exit(0);  }  private void cmdStop() {    sendMessages = false;    logger().info("SSE message sending stopped via CLI");  }  private void cmdStart() {    sendMessages = true;    logger().info("SSE message sending started via CLI");  }  // Helper function for sending an event in SSE format  private void writeEvent(PrintWriter out, String event, String data, String id) {    if (event != null && !event.isEmpty()) {      out.printf("event: %s%n", event);    }    if (id != null && !id.isEmpty()) {      out.printf("id: %s%n", id);    }    if (data != null) {      // Correctly output multiline data      for (String line : data.split("\\R", -1)) {        out.printf("data: %s%n", line);      }    }    out.print("\n"); // terminate message with empty line    out.flush();  }  // Comment-based heartbeat, ignored by client – keeps connection alive  private void heartbeat(PrintWriter out) {    out.print(": keep-alive\n\n");    out.flush();  }}

Quick function test

  • Start: java Application (or  compile/execute via javac/java).
  • Check with a small Java program:
import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;import static java.net.http.HttpClient.newHttpClient;public class SseTestClient {  public static void main(String[] args)      throws Exception {    // Create a new HTTP/2 client    HttpClient client = newHttpClient();    // Build GET request to connect to the SSE endpoint    HttpRequest request = HttpRequest.newBuilder()        .uri(URI.create("http://localhost:8080/sse"))        .GET(        .build();    // Asynchronously send request and consume the response stream line by line    client.sendAsync(request, HttpResponse.BodyHandlers.ofLines())        .thenAccept(response ->            response.body().forEach(System.out::println))        .join();  }}

This simple program opens a connection to the server and outputs the received SSE messages line by line to the console. Continuous event:/id:/data: blocks and : keep-alive comments are expected.

Chapter 4 – Minimal SSE Client in Core Java

4.1 Implementation with HttpClient

On the client side, the JDK has offered a powerful API since Java 11 with java.net.http.HttpClient to process HTTP connections asynchronously. Because SSE is based on a persistent GET request, the client can continuously receive incoming data via HttpClient. In contrast to classic REST requests, which are completed after the body has been entirely accepted, the connection remains open and delivers lines in text/event-stream format.

We encapsulate the implementation in a dedicated class SseClient, which contains no static methods. The client is then started via a separate class SseClientApp.

package com.svenruppert.sse.client;import com.svenruppert.dependencies.core.logger.HasLogger;import java.io.IOException;import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;import java.time.Duration;import java.util.function.Consumer;import java.util.stream.Stream;/** * Minimal, instance-based SSE client built on java.net.http.HttpClient. * - manages Last-Event-ID * - implements a reconnect loop * - parses text/event-stream */public final class SseClient    implements HasLogger, AutoCloseable {  private final HttpClient http;  private final URI uri;  private final Duration reconnectDelay = Duration.ofSeconds(2);  private volatile boolean running = true;  private volatile String lastEventId = null;  public SseClient(URI uri) {    this.uri = uri;    this.http = HttpClient.newBuilder()        .connectTimeout(Duration.ofSeconds(5))        .build();  }  /**   * Starts the streaming loop and invokes the callback for each complete event.   */  public void run(Consumer<SseEvent> onEvent) {    while (running) {      try {        HttpRequest.Builder b = HttpRequest.newBuilder()            .uri(uri)            .timeout(Duration.ofMinutes(10))            .GET();        if (lastEventId != null) {          b.setHeader("Last-Event-ID", lastEventId);        }        HttpRequest req = b.build();        // synchronous streaming so we can parse line by line        HttpResponse<Stream<String>> resp =            http.send(req, HttpResponse.BodyHandlers.ofLines());        if (resp.statusCode() != 200) {          logger().warn("Unexpected status {} from {}", resp.statusCode(), uri);          sleep(reconnectDelay);          continue;        }        try {          parseStream(resp.body(), onEvent);        } catch (java.io.UncheckedIOException uioe) {          // Common case on server shutdown: stream is closed → reconnect gracefully          var cause = uioe.getCause();          logger().info("Stream closed ({}). Reconnecting …",                        cause != null                            ? cause.getClass().getSimpleName()                            : uioe.getClass().getSimpleName());        } catch (RuntimeException re) {          logger().warn("Unexpected runtime exception in parser: {}", re.getMessage());        }      } catch (IOException | InterruptedException e) {        if (!running) break; // terminated normally        logger().warn("Connection interrupted ({}). Reconnecting in {}s …",                      e.getClass().getSimpleName(), reconnectDelay.toSeconds());        sleep(reconnectDelay);      }    }  }  private void parseStream(Stream<String> lines, Consumer<SseEvent> onEvent) {    String event = null, id = null;    StringBuilder data = null;    try {      for (String line : (Iterable<String>) lines::iterator) {        if (line.isEmpty()) {          // finish current message          if (data != null) {            String payload = data.toString();            SseEvent ev = new SseEvent(event, payload, id);            if (id != null) lastEventId = id; // remember progress            // shutdown signal from server → client terminates gracefully            if ("shutdown".equalsIgnoreCase(ev.event())) {              try {                onEvent.accept(ev);              } catch (RuntimeException ex) {                logger().warn("Event callback threw exception: {}", ex.getMessage());              }              this.running = false;              break; // leave parsing loop            }            try {              onEvent.accept(ev);            } catch (RuntimeException ex) {              logger().warn("Event callback threw exception: {}", ex.getMessage());            }          }          event = null;          id = null;          data = null;          continue;        }        if (line.startsWith(":")) {          // comment/heartbeat — silently ignore (avoid log spam)          continue;        }        int idx = line.indexOf(':');        String field = (idx >= 0 ? line.substring(0, idx) : line).trim();        String value = (idx >= 0 ? line.substring(idx + 1) : "");        if (value.startsWith(" ")) value = value.substring(1); // drop optional leading space        switch (field) {          case "event" -> event = value;          case "id" -> id = value;          case "data" -> {            if (data == null) data = new StringBuilder();            if (!data.isEmpty()) data.append(' ');            data.append(value);          }          default -> { /* unknown field ignored */ }        }      }    } catch (java.io.UncheckedIOException uioe) {      // Typically EOF/closed when server stops → do not throw further      var cause = uioe.getCause();      logger().info("Input stream ended ({}).",                    cause != null                        ? cause.getClass().getSimpleName()                        : uioe.getClass().getSimpleName());    }  }  private void sleep(Duration d) {    try {      Thread.sleep(d.toMillis());    } catch (InterruptedException ignored) {      Thread.currentThread().interrupt();    }  }  @Override  public void close() { running = false; }}package com.svenruppert.sse.client;import com.svenruppert.dependencies.core.logger.HasLogger;import java.net.URI;public final class SseClientApp implements HasLogger {  public static void main(String[] args) {    String url = (args.length > 0 ? args[0] : "http://localhost:8080/sse");    URI uri = URI.create(url);    try (SseClient client = new SseClient(uri)) {      Runtime.getRuntime().addShutdownHook(new Thread(client::close));      client.run(ev -> {        // You could branch based on ev.event(); for now we just log        if (ev.id() != null) {          System.out.printf("[%s] id=%s data=%s%n", ev.event(), ev.id(), ev.data());        } else {          System.out.printf("[%s] data=%s%n", ev.event(), ev.data());        }      });    }  }}

4.2 Interpreting Events

The SseClient has a parseEvents(Stream<String>) method that parses incoming rows for event:, data:,  and id: fields and returns them as SseEvent objects. This allows the received data to be structured and processed in a targeted manner.

4.3 Behaviour in case of aborting and reconnect

The infinite loop mechanism implemented in the start() method ensures that the client automatically establishes a new connection in the event of an abort. A short break is taken between reconnects to avoid endless loops in the event of permanent connection problems.

With this architecture, the client is clearly structured: SseClient encapsulates the logic, while SseClientApp is the starting point for execution. This means that the implementation remains modular, testable and platform-independent.

Hints

  • SseClient has no static methods; it is controlled by instance state (running, lastEventId).
  • SseClientApp is the entry point. The URL can be passed as an argument; Standard is http://localhost:8080/sse.
  • Reconnect takes place automatically with the last received Last Event ID.
  • The callback interface (Consumer<SseEvent>) enables flexible further processing (logging, UI updates, persistence, etc.).

Chapter 5 – Testing and Debugging SSE

5.1 Using curl and browser EventSource

To check SSE endpoints, developers often turn to curl because it’s available on almost all platforms. With the -N option  (no buffering) the messages can be made directly visible:

curl -N http://localhost:8080/sse

The received events appear in the terminal in their raw form, including event:, data: and id: fields. An alternative is to use the JavaScript API EventSource in the browser:

const source = new EventSource(“http://localhost:8080/sse&#8221;);

source.onmessage = e = > console.log(e.data);

This allows the behavior of the server to be tracked directly in the browser.

5.2 Checking with Java Client

Since this article deliberately emphasizes platform independence, a separate Java client is a good idea instead of external tools (see chapter 4). This can be used both as a permanent listener and specifically for test cases, for example by consuming only a certain number of events and then terminating them.

Example: A test run that collects exactly five events and then ends:

SseClient client = new SseClient(URI.create("http://localhost:8080/sse"));List<SseEvent> events = new ArrayList<>();client.run(ev -> {  events.add(ev);  if (events.size() >= 5) {    client.close();  }});

This allows functional and integration tests to be carried out directly in the Java environment without dependence on curl or telnet .

5.3 Monitoring and logging

Precise monitoring of SSE connections is indispensable for the operation of productive systems. Monitoring is the systematic recording of key figures such as the number of active clients or the average duration of a connection. Equally important is end-to-end error tracking, which documents occurring IO errors, timeouts and aborted transmissions and thus forms the basis for rapid troubleshooting. In addition, continuous monitoring of the heartbeats ensures that comments or keep-alive signals are sent at regular intervals, keeping the connections stable.

Effective logging supports this monitoring and should be done on both the server and client sides. This makes it possible to isolate network problems or interference caused by proxies more quickly. It is beneficial to record unique identifiers for connections and individual events in the log to make communication paths transparent and comprehensible even in complex scenarios.

These tools can be used to reliably track, reproduce and monitor the behaviour of SSE implementations in production environments.

Chapter 6 – Application Scenarios and Limitations

Server-sent events (SSE) find their strength in fields of application where continuous, unidirectional data transmission from the server to the client is required. It is particularly obvious to use it in the field of notification systems. Here, events such as the arrival of new messages, status changes in a workflow or system warnings can be transmitted directly to users without them having to make repeated requests actively. Another typical scenario is monitoring solutions, in which measured values or system metrics are visualised in real time. SSE also offers a resource-saving option for continuous data delivery in telemetry, for example, in the transmission of sensor data from distributed systems.

At the same time, it is essential to consider the limitations of the procedure. Since SSE only transmits UTF-8 encoded text data, it is not possible to transmit binary content directly. Although binary data can be encoded in text form (e.g. using Base64), this is at the expense of efficiency. SSE is also limited to one-way communication: the server can send data to the client, but not vice versa. For scenarios that require bidirectional exchange, WebSockets or similar technologies are more suitable. Network Restrictive problem infrastructures represent another problem area. Proxies or firewalls can block or disconnect long-term open HTTP connections after a certain amount of time, necessitating an additional reconnect strategy.

Safety aspects should also not be neglected when using SSE. Since the connection is maintained via the HTTP protocol, particular attention must be paid to transport encryption using HTTPS. In addition, mechanisms should be implemented to prevent misuse by unauthorised clients, such as authentication and access control to the SSE endpoint. After all, resource conservation is a central issue: While SSE works much more efficiently than polling, the simultaneous supply of a massive number of clients can lead to a high load on server resources. Scaling strategies such as load balancing or splitting clients across multiple SSE endpoints can help here.

In addition, it makes sense to name the functions provided in the specification in detail. The message structure provides several possible fields: event: determines the type of the message and allows differentiated event handlers in the client; data: contains the actual message body and can be continued across multiple lines, with the client automatically combining the contents into a data block; id: allows each message to be uniquely labeled so that the Last-Event-ID header can be seamlessly continued when the connection is re-established; retry: signals to the client after which time an automatic connection should be established in case the connection is interrupted; finally, comments can be inserted via a leading colon:  which are ignored by the client but used for keep-alive mechanisms. These fields together form the normative framework that every compliant SSE server should meet.

Overall, SSE is suitable for a wide range of real-time scenarios, as long as the inherent limitations are taken into account and compensated for by appropriate architectural decisions. The technology offers an elegant solution for cases where simplicity, standards compliance, and stable, server-side push communication are paramount.

#EventSourcing #Java #serverside #sse

2025-08-17

El Movimiento de Economía Social Solidaria de Ecuador #ESS #SSE #economiasolidaria #ecuador

messe.ec/

Wouter Tebbens ⁂Wtebbens@social.coop
2025-07-09

Since 2016 we have been working on the *Five Pillar framework* for *commons-based business models*. And while it has greatly evolved through practice in commons-collaborative economy programmes and platform coops and #SSE courses, we hadn't published too much about it.

Now here's an introduction with the necessary references: freeknowledge.eu/five-pillar-m

thanks to @femprocomuns, Labcoop & many cooperative commons businesses

#businessmodels #opensource #commons #democratictech #sustainability

2025-06-27

Against all odds, the #RIPESS-led advocacy campaign with government allies North and South and with support of the #UnitedNations Task Force on the Social and Solidarity Economy (#UNTFSSE) succeeded in integrating the social and solidarity economy (#SSE) into the new global Financing for Development Agenda, amidst very acrimonious negotiations that were at times nearly on the verge of collapse.
#SocialSolidarityEconomy

ripess.org/press-release-socia

2025-06-24

The global SSE movement, including @Ripess_Intercontinental other SSE networks, government partners and the UNTFSSE, have long advocated that #SSE – by promoting democratic/participatory governance and the primacy of people and planet before profit and capital – is a strategic means of implementation of the #SDGs that can help correct course in a major way.
#SolidarityEconomy #SustainableDevelopmetGoals

ripess.org/press-release-socia

🅱🅸🅶🅾🆁🆁🅴.🅾🆁🅶bigorre_org
2025-05-21

Shower rain on Solapur airport (India) “VASL 211100Z 2112/2121 19010KT 4000 -RA HZ SCT018 SCT025 BKN090 TEMPO 2112/2116 18007G17 KT 1500 -TSRA -SHRA SCT012 FEW030CB OVC080 BECMG 2115/2117 23007KT 3000 HZ=” : See what it means on bigorre.org/aero/meteo/vasl/en vl

Mr Tech Kingmrtechking
2025-05-14

SSEs secure the network, but a critical gap remains: the browser. It's the last mile where user actions happen & risks live. Browser-native security complements SSE by covering this crucial blind spot.

SSEs Leave a Gap: Why Your Browser Needs Security Now.
2025-05-14

If you are looking for a #SSE library for #php8, I can recommend this for evaluation: github.com/eliashaeussler/sse

Though there is hardly any docs/examples, code looks pretty good to my average PHP dev eyes. Test suite is good.

It worked without any fuss in my hands.

I was able to forward #NTFY messages over to client via SSE (Grug adds another layer of indirection!)

Wilda SoftwareWildaSoftware
2025-05-14

Całkiem niedawno pisaliśmy o Server-Sent Eventach (SSE) i przykładzie w Go, a teraz na tapet wjeżdża Node.js, ale przede wszystkim pełniejsze wytłumaczenie różnic pomiędzy WebSockets i właśnie SSE.

freecodecamp.org/news/server-s

just small circles 🕊smallcircles@social.coop
2025-05-01

@risottobias

What may be interesting is to look at data-star.dev, a #hypermedia library (that blows #htmx out of the water), with a back-end in #golang that can potentially replace an entire typical Rube Goldberg front-end stack, depending on the use case.

The maintainers have very interesting talks on YT to highlight the innovative approach, which involve #SSE. The maintainer uses a bootstrap that by default has #SQLite (and #NATS, which 😬 recently announced relicensing to #BUSL).

Wilda SoftwareWildaSoftware
2025-04-16

Osoby pracujące z web socketami mogą znać też podejście zwane SSE (Server Sent Events), a jeśli nie znają, to ten tekst je wyjaśni. Co prawda, robi to w mniej popularnym , ale nawet, jeśli nie macie z nim do czynienia, to i tak warto zerknąć.

medium.com/@assorium/sse-serve

Client Info

Server: https://mastodon.social
Version: 2025.07
Repository: https://github.com/cyevgeniy/lmst