Beispiel #1
0
        public static RemotableNotification <T> ReadFrom(Stream stream, IRedisValueConverter converter)
        {
            using (var br = new BinaryReader(stream, Encoding.UTF8, leaveOpen: false))
            {
                var value = new RemotableNotification <T>();
                value.Kind = (NotificationKind)br.ReadInt32();
                switch (value.Kind)
                {
                case NotificationKind.OnCompleted:
                    break;

                case NotificationKind.OnError:
                    value.ErrorMessage = br.ReadString();
                    break;

                case NotificationKind.OnNext:
                    using (var restMemory = new MemoryStream())
                    {
                        stream.CopyTo(restMemory);
                        value.Value = converter.Deserialize <T>(restMemory.ToArray());
                    }
                    break;

                default:
                    throw new InvalidOperationException("Invalid Kind");
                }

                return(value);
            }
        }
Beispiel #2
0
        public Task <long> OnError(string errorMessage, CommandFlags commandFlags = CommandFlags.None)
        {
            if (keyType != PubSubKeyType.Normal)
            {
                throw new InvalidOperationException("OnError is supported only PubSubKeyType.Normal");
            }

            using (var ms = new MemoryStream())
            {
                RemotableNotification <T> .OnError(errorMessage).WriteTo(ms, valueConverter);

                return(Connection.Publish(Key, ms.ToArray(), commandFlags));
            }
        }
Beispiel #3
0
        public Task <long> OnCompleted(bool commandFlags)
        {
            if (keyType != PubSubKeyType.Normal)
            {
                throw new InvalidOperationException("OnCompleted is supported only PubSubKeyType.Normal");
            }

            using (var ms = new MemoryStream())
            {
                RemotableNotification <T> .OnCompleted().WriteTo(ms, valueConverter);

                return(Connection.Publish(Key, ms.ToArray(), commandFlags));
            }
        }
Beispiel #4
0
        public Task <long> OnNext(T value, bool queueJump)
        {
            if (keyType != PubSubKeyType.Normal)
            {
                throw new InvalidOperationException("OnNext is supported only PubSubKeyType.Normal");
            }

            using (var ms = new MemoryStream())
            {
                RemotableNotification <T> .OnNext(value).WriteTo(ms, valueConverter);

                return(Connection.Publish(Key, ms.ToArray(), queueJump));
            }
        }
Beispiel #5
0
        public IDisposable Subscribe(IObserver <T> observer)
        {
            var disposable = System.Reactive.Disposables.Disposable.Create(() =>
            {
                if (keyType == PubSubKeyType.Normal)
                {
                    Connection.GetOpenSubscriberChannel().Unsubscribe(Key).Wait();
                }
                else
                {
                    Connection.GetOpenSubscriberChannel().PatternUnsubscribe(Key).Wait();
                }
            });

            var subscribeAction = (Action <string, byte[]>)((_, xs) =>
            {
                using (var ms = new MemoryStream(xs))
                {
                    var value = RemotableNotification <T> .ReadFrom(ms, valueConverter);
                    value.Accept(observer);
                    if (value.Kind == NotificationKind.OnError || value.Kind == NotificationKind.OnCompleted)
                    {
                        disposable.Dispose();
                    }
                }
            });

            // when error, shutdown, close, reconnect? handling?
            if (keyType == PubSubKeyType.Normal)
            {
                Connection.GetOpenSubscriberChannel().Subscribe(Key, subscribeAction).Wait();
            }
            else
            {
                Connection.GetOpenSubscriberChannel().PatternSubscribe(Key, subscribeAction).Wait();
            }

            return(disposable);
        }