示例#1
0
        public static TMessageResponse?PublishAndWaitForExclusiveResponse <TMessageRequest, TMessageResponse>(this INetworkBus bus, TMessageRequest message, int timeout = -1)
            where TMessageRequest : notnull, IMessage, new()
            where TMessageResponse : class, IMessage, new()
        {
            using var firstResponseCancellationTokenSource = new CancellationTokenSource(timeout);
            var firstResponseLock = new TaskCompletionSource <ExclusiveResponseMessage <TMessageRequest> >(TaskCreationOptions.RunContinuationsAsynchronously);

            using var _ = bus.Subscribe <ExclusiveResponseMessage <TMessageRequest> >(msg =>
            {
                firstResponseLock.SetResult(msg);
            }, null);
            bus.Publish(new ExclusiveRequestMessage <TMessageRequest>(), null);

            var firstResponse = firstResponseLock.Task.WaitAsync(firstResponseCancellationTokenSource.Token).WaitAndUnwrapException();

            if (firstResponse == null)
            {
                return(null);
            }


            using var responseCancellationTokenSource = new CancellationTokenSource(timeout);
            var responseLock = new TaskCompletionSource <ExclusiveAcceptedResponseMessage <TMessageResponse> >(TaskCreationOptions.RunContinuationsAsynchronously);

            using var __ = bus.Subscribe <ExclusiveAcceptedResponseMessage <TMessageResponse> >(msg =>
            {
                responseLock.SetResult(msg);
            }, firstResponse.ReferenceId);
            bus.Publish(new ExclusiveAcceptedRequestMessage <TMessageRequest>(message), firstResponse.ReferenceId);

            var response = responseLock.Task.WaitAsync(responseCancellationTokenSource.Token).WaitAndUnwrapException();

            return(response.Response);
        }
示例#2
0
        public static IDisposable SubscribeAndReplyToExclusive <TMessageRequest, TMessageResponse>(this INetworkBus bus, Func <TMessageRequest, Task <bool> > canReply, Func <TMessageRequest, Task <TMessageResponse> > func, Guid requestReferenceId)
            where TMessageRequest : notnull, IMessage, new()
            where TMessageResponse : notnull, IMessage, new()
        {
            var disposable1 = bus.Subscribe <ExclusiveRequestMessage <TMessageRequest> >(async message =>
            {
                if (await canReply(message.Request))
                {
                    bus.Publish(new ExclusiveResponseMessage <TMessageRequest>(requestReferenceId), null);
                }
            }, null);

            var disposable2 = bus.SubscribeAndReply <ExclusiveAcceptedRequestMessage <TMessageRequest> >(async message =>
            {
                return(new ExclusiveAcceptedResponseMessage <TMessageResponse>(await func(message.Request)));
            }, requestReferenceId);

            return(new CompositeDisposable(disposable1, disposable2));
        }
示例#3
0
        public void Publish <T>(string topic, T payload) where T : class
        {
            var data = new byte[0];

            // example, later use protobuf for serialisation
            if (typeof(T) == typeof(string))
            {
                data = Encoding.UTF8.GetBytes((string)(object)payload);
            }
            else if (typeof(T).IsProto())
            {
                // protobuf message
                using (var stream = new MemoryStream())
                {
                    Serializer.Serialize(stream, payload);
                    data = stream.ToArray();
                }
            }

            _networkBus.Publish(topic, data);
        }