Server Send Events - SSL + Trigger

Hi @mythz ,

2 Questions on SSE.

  1. When running in development everything runs on https. So in general api calls I will use something like code below when connecting from a simulator to connect with my localhost as simulator normally reference specific IP to map to localhost. To prevent SSL error I will use code below.

ServerCertificateCustomValidationCallback = (req, cert, chain, errors) =>
return true;

On Server Events is there something that I can use on the “client side” to ignore the SSL errors
similar to code above.

I have tried on server side the code below but I still see the SSL Error

LimitToAuthenticatedUsers = false

SSL Error:

Error : System.Net.WebException: Error: TrustFailure (Authentication failed, see inner exception.) —> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception. —> Mono.Btls.MonoBtlsException: Ssl error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED
at /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/boringssl/ssl/handshake_client.c:1132
at Mono.Btls.MonoBtlsContext.ProcessHandshake () [0x00042] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/System/Mono.Btls/MonoBtlsContext.cs:220

  1. I use the trigger functionality in SSE. On a mobile device I will subscribe to triggers with

sse_client?.AddListener(listenerName, handler);

So I have different tabs in my mobile app that subscribes to between 50-100 triggers at a time when the user selects different tabs to display data in real-time.

I assume each listener call above will trigger a http request to server. So 50-100 trigger per tab will result in many calls.

Is there perhaps a more efficient way to send the triggers to server in bulk so that I only end up with one htttp call to server ?

Thanks again.

The ServerEventsClient.cs only uses .NET’s HttpWebRequest & JsonServiceClient which also uses HttpWebRequest so the global “ignore all SSL errors” should work on all HTTP connections ServerEventsClient makes:

ServicePointManager.ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true;

Otherwise the AllRequestFilters allows you to provide a global Request Filter for all client requests:

var sse = new ServerEventsClient(baseUrl) {
    AllRequestFilters = req => 
        ((HttpWebRequest)req).ServerCertificateValidationCallback = 
            (sender, cert, chain, sslPolicyErrors) => true

I don’t understand what you mean by this, adding a listener is just a client concern for mapping which messages are handled by which handler, adding a listener doesn’t result in any additional server calls nor does it result in any additional messages being sent to the client which only receive messages sent to channels it subscribes to (or messages sent to all channels).

Thanks @mythz.

So you are saying triggers are only client side , therefor it means that if the server send information to say like:

this.ServerEvents.NotifyChannelAsync(“Main”, “trigger.stockLevelsID_100” , message)

The call above will be send to all users / clients on channel “Main” but only the clients that are subscribed to trigger is where the callback will happen ?

Is there a way to send the message to only subscribed clients ? I know you can use channels but in my case that will result in 100’s of channels,

Or let me rephrase what is the most efficient way to notify only those clients that are subscribed to a call without sending to clients that are not listening assuming that there can be thousands of “subscribed topics” collectively on the server side. ?

If client channels was as easy as code below then it would be great but to redefine new ServerEventsClient(connectionstring, channelname) with all events for every “subscribed topic” seems very complicated.

SSE.AddChannel (channelname, handler);

or is the recommended way to simply overwrite the existing ServerEventsClient with all the subscribed topics as “channels” each time the client topics change in which case I first have to stop the existing ServerEventsClient and then restart with updated channels. My concern here is that the stop / restarting process may result in some lost events that got fired from the server as there is then no continues connection on the client side.

Right all clients subscribed to the “Main” channel receive messages sent to the “Main” channel and invoke listeners that messages are targeted for.

No that’s the entire concept of channels, for clients to “subscribe to” to and receive events sent on that channel. If you don’t want to send messages to a channel, you can send them directly to a User or a Users unique subscription.

The different APIs you can use to send a notification is identified by the Notify* APIs in IServerEvents. E.g. in addition to a channel you can send messages to a single user by User Id, UserName or SessionId or a single subscription (i.e. Users can have multiple subscriptions).

You can only “subscribe” to channels which is an artificial group of your own choosing, either at the start of the subscription or later via the Un/SubscribeToChannels APIs which you can have as many of to make it has arbitrarily fine-grained or as coarse as you want it. E.g. If you want every handler to have its own its own channel, that’s up to you.

Use the Un/SubscribeToChannels APIs to change which channels a user is subscribed during an active subscription, you wont need to stop/restart your subscription.

Thanks @mythz. for the clarity on triggers. Channels will work for me. As always , awesome support :+1:

1 Like