All notable changes to the LaunchDarkly's EventSource implementation for C# will be documented in this file. This project adheres to Semantic Versioning.
5.2.0 (2025-02-24)
- Update minimum
LaunchDarkly.Logging
version to2.0.0
to share the same min version as SDK implementations.
- Relaxed dependency constraint to allow use of
LaunchDarkly.Logging
1.x or 2.x.
- Removed EOL target framework .NET Framework 4.5.2. Lowest compatible platform versions are now .NET Core 3.1, .NET Framework 4.6.2, .NET 6.0, and .NET Standard 2.0.
- EventSource now considers any server response with an encoding other than UTF-8 to be invalid. The Server-Sent Events specification states that event streams must always use UTF-8.
ConfigurationBuilder.DefaultEncoding
(no longer relevant since the encoding must be UTF-8).
ConfigurationBuilder. HttpRequestModifier
, for making custom modifications to outgoing HTTP requests. (Thanks, acquleo!)
- Updated
LaunchDarkly.Logging
dependency to 1.0.1, to match the version used in the latest server-side .NET SDK release. Since .NET Framework is stricter about dependency versions than .NET Core, it is desirable to keep transitive dependency versions in sync in all packages used by the SDK.
- Fixed a memory leak in which a
CancellationTokenSource
instance was not disposed of after reading from the stream. This bug was introduced in the 4.0.0 release. (#77)
(The 4.1.0 release was an accidental duplicate of 4.0.0 and did not include these changes.)
ConfigurationBuilder.ResponseStartTimeout
-- added as a more accurately named replacement forConnectionTimeout
.
ConfigurationBuilder.ConnectionTimeout
This release was an accidental duplicate of 4.0.0. Please use 4.1.1 instead.
Starting with this version, the API documentation for the latest release is viewable at https://launchdarkly.github.io/dotnet-eventsource.
The 4.x major version of LaunchDarkly.EventSource
will be used in the upcoming major version releases of LaunchDarkly's .NET-based SDKs. This release streamlines the API, updates platform compatibility, and improves performance.
EventSource.Restart
: this method allows the caller to trigger a connection restart even if there was not an error on the stream.MessageEvent.Name
: previously, the event name was only available as a property ofMessageReceivedEventArgs
.ConfigurationBuilder.DefaultEncoding
: sets the character encoding to use for parsing the stream data if the server did not specify an encoding in itsContent-Type
.ConfigurationBuilder.PreferDataAsUtf8Bytes
: an optional mode in whichEventSource
will read thedata:
property of events as a raw UTF-8 byte array (assuming the stream encoding is UTF-8) to avoid unnecessarily allocating a UTF-16string
. This is meant as an optimization for applications that will be processing the data with a UTF-8-based API such asSystem.Text.Json
.- Simple
EventSource(Uri)
constructor for cases where you do not need any other configuration options. - Standard .NET XML documentation of all public types and methods is now produced in the build.
- The release now publishes a Source Link package.
- The minimum .NET Standard compatibility version is now 2.0.
- The minimum .NET Framework compatibility version is now 4.5.2.
- Logging now works through the new
LaunchDarkly.Logging
facade which is used by LaunchDarkly .NET-based SDKs, instead ofCommon.Logging
. ConfigurationBuilder
methods no longer throw any exceptions, except for one case: passingnull
for the stream URI. In all cases where a property has a maximum and/or minimum value, if you try to set a value outside that range it will simply be changed to the closest valid value. If two properties do not make sense to use together (such as a non-nullHttpClient
and a non-nullHttpMessageHandler
), one will simply override the other as described in the API documentation.ConfigurationBuilder.DelayRetryDuration
is named toInitialRetryDelay
, which more accurately describes its meaning.ConfigurationBuilder.MessageHandler
is renamed toHttpMessageHandler
, since that's the name of its type (also, "message" has other meanings in this API).- The type of
Configuration.HttpContentFactory
is now simplyFunc<HttpContent>
rather than using a custom delegate type. - If you pass a
Dictionary
of headers toConfigurationBuilder.RequestHeaders
, it will now be copied. Previously the configuration retained a reference to the originalDictionary
, which could cause problems if it was later modified. EventSource
now implements the stream read timeout in a way that uses the task scheduler more efficiently. Previously, it executed an additional task for each read withTask.Delay
; now, it uses a timed cancellation token.- Exception messages have been rewritten for clarity and style.
ConfigurationBuilder.BackoffResetThreshold
had no effect; the default value was being used regardless of what you set it to.- When reading the SSE stream,
EventSource
was using a case-insensitive comparison to recognize field names likeevent
anddata
. The SSE specification states that field name "must be compared literally, with no case folding performed," so a field name likeEVENT
is invalid.
- Removed all types and methods that were marked as deprecated/obsolete in the last 3.x version.
Configuration
no longer has a public constructor. Instances must now be created withConfiguration.Builder
.- The helper class
ExponentialBackoffWithDecorrelation
is no longer public.
- You can now tell EventSource to use an
HttpClient
instance that you provide by callingConfigurationBuilder.HttpClient
. (Thanks, thorstenfleischmann!)
- The package now has a specific target for .NET Standard 2.0, in addition to the previous targets of .NET Standard 1.4 and .NET Framework 4.5. There is no functional difference between the 2.0 and 1.4 builds, but it may be desirable for .NET Core/.NET Standard code to be able to avoid linking to any .NET Standard 1.x assemblies.
- If a stream connection is restarted,
EventSource
should send aLast-Event-Id
header if it previously received an event with anid
field. (Thanks, fracek!)
- If you don't explicitly provide an
HttpMessageHandler
in the configuration, EventSource will now use the defaultHttpClient
constructor; previously, it would create an instance of the standard .NETHttpMessageHandler
implementation and tell theHttpClient
to use that. In .NET Framework and .NET Standard, this makes no difference, but in Xamarin, calling the defaultHttpClient
constructor may allow it to use a better HTTP implementation based on native APIs. - Expanded and improved documentation comments.
- The
EventSource
now implementsIDisposable
. CallingDispose()
has the same effect as callingClose()
.
- Under some circumstances, a
CancellationTokenSource
might not be disposed of after making an HTTP request, which could cause a timer object to be leaked.
- The assemblies in this package now have Authenticode signatures. The release note for 3.2.1 was an error; that release did not include signatures.
- The console applications for manual testing have been removed (because the unit tests now include full end-to-end tests against a stub HTTP server).
- The published assemblies are now digitally signed as well as strong-named. Also, they are now built in Release mode and do not contain debug information.
- Previously, the delay before reconnect attempts would increase exponentially only if the previous connection could not be made at all or returned an HTTP error; if it received an HTTP 200 status, the delay would be reset to the minimum even if the connection then immediately failed. Now, the new configuration property
BackoffResetThreshold
(default: 1 minute) specifies the length of time that a connection must stay active in order for the reconnect delay to be reset. (#37)
-
Fixed an unobserved exception that could occur following a stream timeout, which could cause a crash in .NET 4.0.
-
A
NullReferenceException
could sometimes be logged if a stream connection failed. (#24)
Duplicate of 3.1.4, created due to a problem in the release process.
- Fixed a bug that prevented the event source from reconnecting to the stream if it received an HTTP error status from the server (as opposed to simply losing the connection).
- The reconnection attempt counter is no longer shared among all EventSource instances. Previously, if you connected to more than one stream, all but the first would behave as if they were reconnecting and would have a backoff delay.
- The SDK was referencing some system assemblies via
<PackageReference>
, which could cause dependency conflicts. These have been changed to framework<Reference>
s. A redundant reference toSystem.Runtime
was removed.
- If the stream connection fails, there should be an increasing backoff interval before each reconnect attempt. Previously, it would log a message about waiting some number of milliseconds, but then not actually wait.
- Removed an unused dependency on Newtonsoft.Json.
- The new class
ConfigurationBuilder
provides a validated fluent builder pattern forConfiguration
instances. - The HTTP method and request body can now be specified in
ConfigurationBuilder
or in theConfiguration
constructor. The default is still to useGET
and not send a request body.
- Logging is now done via
Common.Logging
.
EventSource
now uses the interfaceIEventSource
.
- Downgrade Microsoft.Extensions.Logging to 1.0.2 to reduce dependencies brought in when building against .NET Framework.
- Exposed
EventSourceServiceCancelledException
as a public class.
- Removed unused and transitive dependencies.
- Added a reference to the Apache 2.0 license in
LaunchDarkly.EventSource.csproj
- Improved logging. Thanks @JeffAshton!
- Move from .NET Standard 1.6 to 1.4.
- Exposed the
ExponentialBackoffWithDecorrelation
as a public class. This class may be used to calculate exponential backoff with jitter.
- Reconnects to EventSource are now handled inline, rather than using Polly for managing retry policies.
- Removed the
closeOnEndOfStream
property.
ConnectToEventSourceAsync
now takes in a new boolean parameter,closeOnEndOfStream
, which, if true, will close the EventSource connection when the end of the stream is reached.
- Fixed a bug causing causing read timeouts to never propogate.
- Signed EventSource Assembly.
- Change dependency on Polly to Polly-Signed.
Hello world!