Class EventSource
- java.lang.Object
-
- com.launchdarkly.eventsource.EventSource
-
- All Implemented Interfaces:
java.io.Closeable,java.lang.AutoCloseable
public class EventSource extends java.lang.Object implements java.io.CloseableThe SSE client.By default, EventSource makes HTTP requests using OkHttp, but it can be configured to read from any input stream. See
ConnectStrategyandHttpConnectStrategy.Instances are always configured and constructed with
EventSource.Builder. The client is created in an inactive state.The client uses a pull model where the caller starts the EventSource and then requests data from it synchronously on a single thread. The initial connection attempt is made when you call
start(), or when you first attempt to read an event. To read events from the stream, you can either request them one at a time by callingreadMessage()orreadAnyEvent(), or consume them in a loop by callingmessages()oranyEvents(). The "message" methods assume you are only interested inMessageEventdata, whereas the "anyEvent" methods also provide other kinds of stream information. These are blocking methods with no timeout; if you need a timeout mechanism, consider reading from the stream on a worker thread and using a queue such asBlockingQueueto consume the messages elsewhere.If, instead of managing your own thread to read from the stream, you would like to have events pushed to you from a worker thread that the library maintains, use
BackgroundEventSource.Note that although
EventSourceis named after the JavaScript API that is described in the SSE specification, its behavior is not necessarily identical to standard web browser implementations of EventSource: by default, it will automatically retry (with a backoff delay) for some error conditions where a browser will not retry, and it also supports request configuration options (such as request headers and method) that the browser EventSource does not support. However, its interpretation of the stream data is fully conformant with the SSE specification, unless you use the opt-in modeEventSource.Builder.streamEventData(boolean)which allows for greater efficiency in some use cases but has some behavioral constraints.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classEventSource.BuilderBuilder for configuringEventSource.
-
Field Summary
Fields Modifier and Type Field Description static intDEFAULT_READ_BUFFER_SIZEThe default value forEventSource.Builder.readBufferSize(int).static longDEFAULT_RETRY_DELAY_MILLISThe default value forEventSource.Builder.retryDelay(long, TimeUnit): 1 second.static longDEFAULT_RETRY_DELAY_RESET_THRESHOLD_MILLISThe default value forEventSource.Builder.retryDelayResetThreshold(long, TimeUnit): 60 seconds.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description java.lang.Iterable<StreamEvent>anyEvents()Returns an iterable sequence of events.booleanawaitClosed(long timeout, java.util.concurrent.TimeUnit timeUnit)Blocks until all underlying threads have terminated and resources have been released.voidclose()Permanently shuts down the EventSource.longgetBaseRetryDelayMillis()Returns the current base retry delay.java.lang.StringgetLastEventId()Returns the ID value, if any, of the last known event.LDLoggergetLogger()Returns the logger that this EventSource is using.longgetNextRetryDelayMillis()Returns the retry delay that will be used for the next reconnection, if the stream has failed.java.net.URIgetOrigin()Returns the stream URI.ReadyStategetState()Returns an enum indicating the current status of the connection.voidinterrupt()Stops the stream connection if it is currently active.java.lang.Iterable<MessageEvent>messages()Returns an iterable sequence of SSE messages.StreamEventreadAnyEvent()Attempts to receive an event of any kind from the stream.MessageEventreadMessage()Attempts to receive a message from the stream.voidstart()Attempts to start the stream if it is not already active.voidstop()Stops the stream connection if it is currently active.
-
-
-
Field Detail
-
DEFAULT_RETRY_DELAY_MILLIS
public static final long DEFAULT_RETRY_DELAY_MILLIS
The default value forEventSource.Builder.retryDelay(long, TimeUnit): 1 second.- See Also:
- Constant Field Values
-
DEFAULT_RETRY_DELAY_RESET_THRESHOLD_MILLIS
public static final long DEFAULT_RETRY_DELAY_RESET_THRESHOLD_MILLIS
The default value forEventSource.Builder.retryDelayResetThreshold(long, TimeUnit): 60 seconds.- See Also:
- Constant Field Values
-
DEFAULT_READ_BUFFER_SIZE
public static final int DEFAULT_READ_BUFFER_SIZE
The default value forEventSource.Builder.readBufferSize(int).- See Also:
- Constant Field Values
-
-
Method Detail
-
getOrigin
public java.net.URI getOrigin()
Returns the stream URI.- Returns:
- the stream URI
- Since:
- 4.0.0
-
getLogger
public LDLogger getLogger()
Returns the logger that this EventSource is using.- Returns:
- the logger
- Since:
- 4.0.0
- See Also:
EventSource.Builder.logger(LDLogger)
-
getState
public ReadyState getState()
Returns an enum indicating the current status of the connection.- Returns:
- a
ReadyStatevalue
-
getLastEventId
public java.lang.String getLastEventId()
Returns the ID value, if any, of the last known event.This can be set initially with
EventSource.Builder.lastEventId(String), and is updated whenever an event is received that has an ID. Whether event IDs are supported depends on the server; it may ignore this value.- Returns:
- the last known event ID, or null
- Since:
- 2.0.0
- See Also:
EventSource.Builder.lastEventId(String)
-
getBaseRetryDelayMillis
public long getBaseRetryDelayMillis()
Returns the current base retry delay.This is initially set by
EventSource.Builder.retryDelay(long, TimeUnit), orDEFAULT_RETRY_DELAY_MILLISif not specified. It can be overriden by the stream provider if the stream contains a "retry:" line.The actual retry delay for any given reconnection is computed by applying the configured
RetryDelayStrategyto this value.- Returns:
- the base retry delay in milliseconds
- Since:
- 4.0.0
- See Also:
getNextRetryDelayMillis()
-
getNextRetryDelayMillis
public long getNextRetryDelayMillis()
Returns the retry delay that will be used for the next reconnection, if the stream has failed.If you have just received a
StreamExceptionorFaultEvent, this value tells you how long EventSource will sleep before reconnecting, if you tell it to reconnect by callingstart()or by trying to read another event. The value is computed by applying the configuredRetryDelayStrategyto the current value ofgetBaseRetryDelayMillis().At any other time, the value is undefined.
- Returns:
- the next retry delay in milliseconds
- Since:
- 4.0.0
- See Also:
getBaseRetryDelayMillis()
-
start
public void start() throws StreamExceptionAttempts to start the stream if it is not already active.If there is not an active stream connection, this method attempts to start one using the previously configured parameters. If successful, it returns and you can proceed to read events. You should only read events on the same thread where you called
start().If the connection fails, the behavior depends on the configured
ErrorStrategy. The default strategy is to throw aStreamException, but you can configure it to continue instead, in which casestart()will keep retrying until the ErrorStrategy says to give up.If the stream was previously active and then failed,
start()will sleep for some amount of time-- the retry delay-- before trying to make the connection. The retry delay is determined by several factors: seeEventSource.Builder.retryDelay(long, TimeUnit),EventSource.Builder.retryDelayStrategy(RetryDelayStrategy), andEventSource.Builder.retryDelayResetThreshold(long, TimeUnit).- Throws:
StreamException-You do not necessarily need to call this method; it is implicitly called if you try to read an event when the stream is not active. Call it only if you specifically want to confirm that the stream is active before you try to read an event.
If the stream is already active, calling this method has no effect.
StreamException- if the connection attempt failed
-
readMessage
public MessageEvent readMessage() throws StreamException
Attempts to receive a message from the stream.If the stream is not already active, this calls
start()to establish a connection.As long as the stream is active, the method blocks until a message is available. If the stream fails, the default behavior is to throw a
StreamException, but you can configure anErrorStrategyto allow the client to retry transparently instead.This method must be called from the same thread that first started using the stream (that is, the thread that called
start()or read the first event).- Returns:
- an SSE message
- Throws:
StreamException- if there is an error and retry is not enabled- Since:
- 4.0.0
- See Also:
readAnyEvent(),messages()
-
readAnyEvent
public StreamEvent readAnyEvent() throws StreamException
Attempts to receive an event of any kind from the stream.This is similar to
readMessage(), except that instead of specifically requesting aMessageEventit also applies to the other subclasses ofStreamEvent:StartedEvent,FaultEvent, andCommentEvent. Use this method if you want to be informed of any of those occurrences.The error behavior is the same as
readMessage(), except that if theErrorStrategyis configured to let the client continue with an automatic retry, you will receive aFaultEventdescribing the error first, and then aStartedEventonce the stream is reconnected.This method must be called from the same thread that first started using the stream (that is, the thread that called
start()or read the first event).- Returns:
- an event
- Throws:
StreamException- if there is an error and retry is not enabled- Since:
- 4.0.0
- See Also:
readMessage(),anyEvents()
-
messages
public java.lang.Iterable<MessageEvent> messages()
Returns an iterable sequence of SSE messages.This is similar to calling
readMessage()in a loop. If the stream has not already been started, it also starts the stream.The error behavior is different from
readMessage(): if an error occurs and theErrorStrategydoes not allow the client to continue, it simply stops iterating, rather than throwing an exception. If you need to be able to specifically detect errors, usereadMessage().This method must be called from the same thread that first started using the stream (that is, the thread that called
start()or read the first event).- Returns:
- a sequence of SSE messages
- Since:
- 4.0.0
- See Also:
readAnyEvent(),messages()
-
anyEvents
public java.lang.Iterable<StreamEvent> anyEvents()
Returns an iterable sequence of events.This is similar to calling
readAnyEvent()in a loop. If the stream has not already been started, it also starts the stream.The error behavior is different from
readAnyEvent(): if an error occurs and theErrorStrategydoes not allow the client to continue, it simply stops iterating, rather than throwing an exception. If you need to be able to specifically detect errors, usereadAnyEvent()(or, use theErrorStrategymechanism to cause errors to be reported asFaultEvents).This method must be called from the same thread that first started using the stream (that is, the thread that called
start()or read the first event).- Returns:
- a sequence of events
- Since:
- 4.0.0
- See Also:
readAnyEvent(),messages()
-
interrupt
public void interrupt()
Stops the stream connection if it is currently active.Unlike the reading methods, you are allowed to call this method from any thread. If you are reading events on a different thread, and automatic retries are not enabled by an
ErrorStrategy, the other thread will receive aStreamClosedByCallerException.The difference between this method and
stop()is only relevant if automatic retries are enabled. In this case, if you are using themessages()oranyEvents()iterator to read events, callinginterrupt()will cause the stream to be closed and then immediately reconnected, whereasstop()will close it and then the iterator will end. In either case, if you explicitly try to read another event it will start the stream again.If the stream is not currently active, calling this method has no effect.
Note for Android developers: since it is generally undesirable to perform any network activity from the main thread, be aware that
interrupt(),stop(), andclose()all cause an immediate close of the connection (if any), which happens on the same thread that called the method.
-
stop
public void stop()
Stops the stream connection if it is currently active.Unlike the reading methods, you are allowed to call this method from any thread. If you are reading events on a different thread, and automatic retries are not enabled by an
ErrorStrategy, the other thread will receive aStreamClosedByCallerException.The difference between this method and
interrupt()is only relevant if automatic retries are enabled. In this case, if you are using themessages()oranyEvents()iterator to read events, callinginterrupt()will cause the stream to be closed and then immediately reconnected, whereasstop()will close it and then the iterator will end. In either case, if you explicitly try to read another event it will start the stream again.If the stream is not currently active, calling this method has no effect.
Note for Android developers: since it is generally undesirable to perform any network activity from the main thread, be aware that
interrupt(),stop(), andclose()all cause an immediate close of the connection (if any), which happens on the same thread that called the method.- Since:
- 4.0.0
- See Also:
interrupt(),start()
-
close
public void close()
Permanently shuts down the EventSource.This is similar to
stop()except that it also releases any resources that the EventSource was maintaining in general, such as an HTTP connection pool. Do not try to use the EventSource after closing it.Note for Android developers: since it is generally undesirable to perform any network activity from the main thread, be aware that
interrupt(),stop(), andclose()all cause an immediate close of the connection (if any), which happens on the same thread that called the method.- Specified by:
closein interfacejava.lang.AutoCloseable- Specified by:
closein interfacejava.io.Closeable
-
awaitClosed
public boolean awaitClosed(long timeout, java.util.concurrent.TimeUnit timeUnit) throws java.lang.InterruptedExceptionBlocks until all underlying threads have terminated and resources have been released.- Parameters:
timeout- maximum time to wait for everything to shut down, in whatever time unit is specified bytimeUnittimeUnit- the time unit, orTimeUnit.MILLISECONDSif null- Returns:
trueif all thread pools terminated within the specified timeout,falseotherwise- Throws:
java.lang.InterruptedException- if this thread is interrupted while blocking
-
-