SSE Listeners Events

Hi Guys,

Hope someone can point me in the right direction. I have a couple of questions regarding SSE.

The release notes mentions listeners on SSE : client.AddListener(“customEvent”, s => updateUI(s));

In the docs I don’t see anything of how to send a message to listeners (pub/sub triggers).
I tried the following without success:

public IEventSubscription Events { get; set; }
this.Events.Publish(“customEvent”, request.Message);

How do I send a message to “customEvent” from the server side?

Also, is there a way to register some properties when a user connects to SSE and then using these properties in LINQ to send a message:

Example - On User connection to SSE register the following properties:
Email : user@email.com
Company : ABC Corporation
City : New York
Country : USA
Age : 35
Status : Active

and then sending a message to a specific group using linq ==> Notify( x=>x.Company == “ABC Corporation” &&
x.Age > 30 && x.City == “New York” && x.Status == “Active” , “Hello there from server”)

Thanks in advance.

I’ve just added docs on triggering and handling custom events with C# Server Events Client.

There’s no Server API to send based on an arbitrary LINQ expression, but you can do something like adding this info with the OnCreated event, e.g:

new ServerEventsFeature {
    OnCreated = (sub,req) => {
        var session = req.GetSession();
        if (!session.IsAuthenticated) return;
        sub.ConnectArgs["Email"] = session.Email;
        sub.ConnectArgs["Company"] = session.Company;
    }
}

Any info added to ConnectArgs is only visible to the client making the subscription on initial connection, whilst anything added to sub.Meta is visible to everyone handling the User onJoin/onLeave/onUpdate events. I’ve also added ServerArgs for metadata about a subscription that you don’t want sent to any client.

I’ve just made a change to preserve changes to ConnectArgs added in the OnCreated event in this commit so you’ll need to use the v4.5.9 release on MyGet to use OnCreated to modify the ConnectArgs like this.

Once it’s populated the only way to apply specific targeting like your example is to scan all active subscriptions like:

var allSubs = ServerEvents.GetAllSubscriptionInfos();
foreach (var info in allSubs)
{
    string company;
    if (info.TryGetValue("Company", out company) == "ABC Corporation")
        ServerEvents.NotifySubscription(info.SubscriptionId, ...);
}

GetAllSubscriptionInfos() is a new API that was just added in v4.5.9 on MyGet also

Another option I can think of is to use client filtering by having your Message DTO implement a customer property like Filter, e.g:

ServerEvents.NotifyChannel(channel, new CustomEvent {
    Filter = "Company=ABC Corporation&Age=30",
    ...
});

Then your clients CustomEvent handler will split the filter and use it to compare it with the connectionInfo it received on connection which it uses to only execute the event unless it matches all filters.

They’re basically the only 2 approaches I can think of.

Hi Mythz,

Awesome stuff, triggers are now all OK.

I could not test your recommendation on:

OnCreated = (sub,req) => {
var session = req.GetSession();
if (!session.IsAuthenticated) return;
sub.ConnectArgs[“Email”] = session.Email;
sub.ConnectArgs[“Company”] = session.Company;
}

When I install servicestack 4.5.9 from myget into my PCL (profile7) , I get namespace “JsonHttpClient” not found.

Another thing I noticed is, when using displayname in my existing code to display the email address of the user. the email address changes. I authenticate the SSE session from a JWT (use cookie option) from my normal servicestack authentication code.

On my .net core server side the displayname in SSE will change from name.something@gmail.com to name_something_gmail_com Not sure if this is the correct behaviour as I can’t use this property now?

Thanks again.

@Johan It was the issue with the package ServiceStack.HttpClient 4.5.9, it did not contain PCL version of the library. I republished the fixed package to MyGet, you need to clear nuget cache and reinstall ServiceStack.HttpClient package.

Can you try re-downloading the MyGet packages, we resolved a build issue with our CI.

We do ensure the displayName is safe to display as a UserName so it’s initially populated with non-friendly chars replaced with _ but you should be able to use the OnCreated hook to override the Meta["displayName"] that’s used.

I get the following error now in my UWP / PCL project trying to use 4.5.9 after clearing nuget , uninstalling and reinstalling all SS libs:

“Could not load file or assembly ‘System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’. The located assembly’s manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)”

If I downgrade the projects to 4.5.8 all works perfect again.

I’m still investigating this issue, but you should be able to use the .NET Standard version of HttpClient by installing the ServiceStack.HttpClient.Core NuGet package.

Ok you should now be able to reference v4.5.9 ServiceStack.HttpClient NuGet package on MyGet after clearing your NuGet cache.

Errors no more in 4.5.9 :smile:

Using:

sub.ConnectArgs[“Email”] = session.Email;
sub.ServerArgs[“Email”] = session.Email;

in the onCreated() methods both gives me a null on backend. I can assign to ConnectArgs but ServerArgs immediately throws a looping null reference.

ServerArgs is null because it’s optional and not populated, you’ll need to populate it with a Dictionary if you want to use it.

Hi Mythz , I can assign the dictionary but it does not stay persistent on the backend.

This should now be resolved from latest v4.5.9 that’s on MyGet.

Excellent, all work as expected.

Must say, if you ever thinking of enhancing SS with the power of LINQ on the notification layer you will have a “ludicrously awesome” product ;))

Thanks for the fantastic support.

1 Like