Beispiel #1
0
        public override Task ProcessRequestAsync(IRequest req, IResponse res, string operationName)
        {
            res.ContentType = MimeTypes.ServerSentEvents;
            res.AddHeader(HttpHeaders.CacheControl, "no-cache");
            res.KeepAlive = true;
            res.Flush();

            var          serverEvents = req.TryResolve <IServerEvents>();
            IAuthSession session      = req.GetSession();
            var          userAuthId   = session != null ? session.UserAuthId : null;
            var          anonUserId   = serverEvents.GetNextSequence("anonUser");
            var          userId       = userAuthId ?? ("-" + anonUserId);
            var          displayName  = session.GetSafeDisplayName()
                                        ?? "user" + anonUserId;

            var feature = HostContext.GetPlugin <ServerEventsFeature>();

            var now            = DateTime.UtcNow;
            var subscriptionId = SessionExtensions.CreateRandomSessionId();
            var subscription   = new EventSubscription(res)
            {
                CreatedAt       = now,
                LastPulseAt     = now,
                Channel         = req.QueryString["channel"] ?? EventSubscription.UnknownChannel,
                SubscriptionId  = subscriptionId,
                UserId          = userId,
                UserName        = session != null ? session.UserName : null,
                DisplayName     = displayName,
                SessionId       = req.GetPermanentSessionId(),
                IsAuthenticated = session != null && session.IsAuthenticated,
                Meta            =
                {
                    { "userId",                           userId                                                                 },
                    { "displayName",                      displayName                                                            },
                    { AuthMetadataProvider.ProfileUrlKey, session.GetProfileUrl() ?? AuthMetadataProvider.DefaultNoProfileImgUrl },
                }
            };

            if (feature.OnCreated != null)
            {
                feature.OnCreated(subscription, req);
            }

            var heartbeatUrl = req.ResolveAbsoluteUrl("~/".CombineWith(feature.HeartbeatPath))
                               .AddQueryParam("id", subscriptionId);
            var unRegisterUrl = req.ResolveAbsoluteUrl("~/".CombineWith(feature.UnRegisterPath))
                                .AddQueryParam("id", subscriptionId);
            var privateArgs = new Dictionary <string, string>(subscription.Meta)
            {
                { "id", subscriptionId },
                { "unRegisterUrl", unRegisterUrl },
                { "heartbeatUrl", heartbeatUrl },
                { "heartbeatIntervalMs", ((long)feature.HeartbeatInterval.TotalMilliseconds).ToString(CultureInfo.InvariantCulture) }
            };

            if (feature.OnConnect != null)
            {
                feature.OnConnect(subscription, privateArgs);
            }

            serverEvents.Register(subscription, privateArgs);

            var tcs = new TaskCompletionSource <bool>();

            subscription.OnDispose = _ =>
            {
                try
                {
                    res.EndHttpHandlerRequest(skipHeaders: true);
                }
                catch { }
                tcs.SetResult(true);
            };

            return(tcs.Task);
        }