ServiceStack / Issues

Issue Tracker for the commercial versions of ServiceStack
11 stars 6 forks source link

UpdateEventSubscriber responds 200 but doesn't update subscription #710

Closed lomithrani closed 4 years ago

lomithrani commented 4 years ago

Servicestack v5.8.0 netcoreapp3.1 x64 ss-utils.js

Registering as such:

container.Register<IServerEvents>(new MemoryServerEvents());
Plugins.Add(
new ServerEventsFeature()
            {
                HeartbeatInterval = TimeSpan.FromSeconds(10),
                IdleTimeout = TimeSpan.FromSeconds(21),
                LimitToAuthenticatedUsers = true,
                ValidateUserAddress = false,      
                OnSubscribe = (ev) =>{ //stuff },               
                OnUnsubscribe = (ev) => { //stuff }
            });

I'm initialising the the client

 $scope.SSE = new EventSource("/event-stream?channel=editDocs", { withCredentials: true });

        $($scope.SSE).handleServerEvents({
            handlers: {
                onConnect: function (sub) {

                },
                onJoin: function (user) {

                },
                onLeave: function (user) {

                },
                onMessage: function (msg, e) { 
                },
                ValidationObj: function (obj, e) {
                },
                EditDocEvent: function (obj, e) {
                    switch (obj.Method) {
                        case "add":
                            //stuff
                            break;
                        case "remove":
                          //stuff
                            break;
                        default:
                        // code block
                    }
                    $scope.$apply();
                }
            },
            receivers: {
            },
        });

Everything works fine until then but then I want to update the subscription's channels doing that :

$.ss.subscribeToChannels([id_doc], (success) => console.log(success), (error) => console.log("error"));

image

and get this response

image

And a call to /event-subscribers will still say that I'm only registered to /editDocs and not both channels.

I might be wrong but I don't think this is the expected behavior.

Thanks a lot for your hard work !

lomithrani commented 4 years ago

changing the following in ss-utils.js seems to fix my issue

$.ss.updateSubscriber = function (data, cb, cbError) {
        if (!$.ss.updateSubscriberUrl)
            throw new Error("updateSubscriberUrl was not populated");
        return $.ajax({
            type: "POST",
            url: `${$.ss.updateSubscriberUrl}/${$.ss.eventOptions.id}`,
            data: data,
            dataType: "json",
            success: function (r) {
                $.ss.updateSubscriberInfo(data.SubscribeChannels, data.UnsubscribeChannels);
                r.channels = $.ss.eventChannels;
                if (cb != null)
                    cb(r);
            },
            error: function (e) {
                $.ss.reconnectServerEvents({ errorArgs: arguments });
                if (cbError != null)
                    cbError(e);
            }
        });
    };

It doesn't seems to trigger serverEvents OnSubscribe though but that might be expected

mythz commented 4 years ago

Thanks for reporting this! the issue is on the server when constructing the updateSubscriberUrl which should now be resolved from this commit.

Note: you don't need to register MemoryServerEvents as it's pre-registered by default:

//container.Register<IServerEvents>(new MemoryServerEvents());

The OnSubscribe/OnSubscribeAsync is only fired when a new subscription is created not updated, it also only fires the onUpdate event on the client.

This change is available in the latest v5.8.1 that's now available on MyGet.

lomithrani commented 4 years ago

Thank you very much @mythz ! What would you suggest to do server side (as I do some logic on subscribe and unsubscribe) ? Is there any event fired when this update is made ?

mythz commented 4 years ago

I've added a OnUpdateAsync server event on ServerEventsFeature you can use to invoke custom logic when a subscription is updated.

This change is now available from v5.8.1 on MyGet, if you already have v5.8.1 installed you'll need to clear your NuGet packages cache to download the latest version.

lomithrani commented 4 years ago

@mythz Perfect , just a small issue there that I could solve with some logic on my side but I think it might be useful to add we are missing which channels we unsubscribe from during the updates.

mythz commented 4 years ago

In IEventSubscription the active channels are maintained in Channels whilst MergedChannels contains both active and previously subscribed channels, so the difference of MergedChannels-Channels contains the list of unsubscribed channels during the update.