Class EventSource
- All Implemented Interfaces:
Closeable,AutoCloseable
By default, EventSource makes HTTP requests using OkHttp, but it can be configured
to read from any input stream. See ConnectStrategy and HttpConnectStrategy.
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 calling
readMessage() or readAnyEvent(), or consume them in a loop by calling
messages() or anyEvents(). The "message" methods assume you are only
interested in MessageEvent data, 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 as BlockingQueue to 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 EventSource is 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 mode
EventSource.Builder.streamEventData(boolean) which allows for greater efficiency in some use
cases but has some behavioral constraints.
-
Nested Class Summary
Nested Classes -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intThe default value forEventSource.Builder.readBufferSize(int).static final longThe default value forEventSource.Builder.retryDelay(long, TimeUnit): 1 second.static final longThe default value forEventSource.Builder.retryDelayResetThreshold(long, TimeUnit): 60 seconds. -
Method Summary
Modifier and TypeMethodDescriptionReturns an iterable sequence of events.booleanawaitClosed(long timeout, TimeUnit timeUnit) Blocks until all underlying threads have terminated and resources have been released.voidclose()Permanently shuts down the EventSource.longReturns the current base retry delay.Returns the ID value, if any, of the last known event.Returns the logger that this EventSource is using.longReturns the retry delay that will be used for the next reconnection, if the stream has failed.Returns the stream URI.getState()Returns an enum indicating the current status of the connection.voidStops the stream connection if it is currently active.messages()Returns an iterable sequence of SSE messages.Attempts to receive an event of any kind from the stream.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 Details
-
DEFAULT_RETRY_DELAY_MILLIS
public static final long DEFAULT_RETRY_DELAY_MILLISThe default value forEventSource.Builder.retryDelay(long, TimeUnit): 1 second.- See Also:
-
DEFAULT_RETRY_DELAY_RESET_THRESHOLD_MILLIS
public static final long DEFAULT_RETRY_DELAY_RESET_THRESHOLD_MILLISThe default value forEventSource.Builder.retryDelayResetThreshold(long, TimeUnit): 60 seconds.- See Also:
-
DEFAULT_READ_BUFFER_SIZE
public static final int DEFAULT_READ_BUFFER_SIZEThe default value forEventSource.Builder.readBufferSize(int).- See Also:
-
-
Method Details
-
getOrigin
Returns the stream URI.- Returns:
- the stream URI
- Since:
- 4.0.0
-
getLogger
Returns the logger that this EventSource is using.- Returns:
- the logger
- Since:
- 4.0.0
- See Also:
-
getState
Returns an enum indicating the current status of the connection.- Returns:
- a
ReadyStatevalue
-
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:
-
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
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:
-
start
Attempts 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
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
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:
-
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:
-
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:
-
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:
-
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 interfaceAutoCloseable- Specified by:
closein interfaceCloseable
-
awaitClosed
Blocks 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:
InterruptedException- if this thread is interrupted while blocking
-