001/* 002 * Copyright 2022-2025 Revetware LLC. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.soklet.core; 018 019import javax.annotation.Nonnull; 020 021/** 022 * Broadcasts a <a href="https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events">Server-Sent Event</a> payload to all clients listening on a {@link ResourcePath}. 023 * <p> 024 * For example: 025 * <pre>{@code // Acquire our SSE broadcaster (sends to anyone listening to "/examples/123") 026 * ServerSentEventServer server = ...; 027 * ServerSentEventBroadcaster broadcaster = server.acquireBroadcaster(ResourcePath.of("/examples/123")).get(); 028 * 029 * // Create our SSE payload 030 * ServerSentEvent serverSentEvent = ServerSentEvent.withEvent("test") 031 * .data("example") 032 * .build(); 033 * 034 * // Publish SSE payload to all listening clients 035 * broadcaster.broadcast(serverSentEvent);}</pre> 036 * <p> 037 * Soklet guarantees exactly one {@link ServerSentEventBroadcaster} instance exists per {@link ResourcePath}. Soklet is responsible for the creation and management of {@link ServerSentEventBroadcaster} instances. 038 * <p> 039 * You may acquire a broadcaster via {@link ServerSentEventServer#acquireBroadcaster(ResourcePath)}. 040 * <p> 041 * See <a href="https://www.soklet.com/docs/server-sent-events">https://www.soklet.com/docs/server-sent-events</a> for detailed documentation. 042 * <p> 043 * Formal specification is available at <a href="https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events">https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events</a>. 044 * 045 * @author <a href="https://www.revetkn.com">Mark Allen</a> 046 */ 047public interface ServerSentEventBroadcaster { 048 /** 049 * The runtime Resource Path with which this broadcaster is associated. 050 * <p> 051 * Soklet guarantees exactly one {@link ServerSentEventBroadcaster} instance exists per {@link ResourcePath}. 052 * <p> 053 * For example, a client may register for SSE broadcasts for <em>Resource Method</em> {@code @ServerSentEventSource("/examples/{exampleId}")} by making a request to {@code GET /examples/123}. 054 * <p> 055 * A broadcaster specific to {@code /examples/123} is then created (if necessary) and managed by Soklet, and can be used to send SSE payloads to all clients via {@link #broadcast(ServerSentEvent)}. 056 * 057 * @return the runtime Resource Path instance with which this broadcaster is associated 058 */ 059 @Nonnull 060 ResourcePath getResourcePath(); 061 062 /** 063 * Approximately how many clients are listening to this broadcaster's {@link ResourcePath}? 064 * <p> 065 * For performance reasons, this number may be an estimate, or a snapshot of a recent moment-in-time. 066 * It's possible for some clients to have already disconnected, but we won't know until we attempt to broadcast to them. 067 * 068 * @return the approximate number of clients who will receive a broadcasted event 069 */ 070 @Nonnull 071 Long getClientCount(); 072 073 /** 074 * Broadcasts a Server-Sent Event payload to all clients listening to this broadcaster's {@link ResourcePath}. 075 * <p> 076 * In practice, implementations will generally return "immediately" and broadcast operation[s] will occur on separate threads of execution. 077 * <p> 078 * However, mock implementations may wish to block until broadcasts have completed - for example, to simplify automated testing. 079 * 080 * @param serverSentEvent the Server-Sent Event payload to broadcast 081 */ 082 void broadcast(@Nonnull ServerSentEvent serverSentEvent); 083}