rebus-org / Rebus

:bus: Simple and lean service bus implementation for .NET
https://mookid.dk/category/rebus
Other
2.3k stars 356 forks source link

Rebus SignalR backplane #857

Closed rsivanov closed 4 years ago

rsivanov commented 4 years ago

Hello!

Have you thought about making an analogue of MassTransit.SignalR backplane, but for Rebus?

mookid8000 commented 4 years ago

No, hadn't thought about that.

What would be the benefit of using Rebus as a layer between SignalR and the backplane?

rsivanov commented 4 years ago

It wouldn't be a layer between SignalR and the backplane - it would be the backplane itself. You wouldn't need to use a separate backplane like Redis, if you already have Rebus (possibly backed by RabbitMq) in your infrastructure. That's what MassTransit.SignalR does.

mookid8000 commented 4 years ago

Ok, I see... it's just kinda funny that SignalR has an IMessageBus abstraction, which would then be implemented by Rebus, which is itself also an abstraction..... abstractionception!? 🤓

But ok, it would make it possible to use any Rebus-supported transport as a SignalR backplane, and I guess that would be neat. 🙂

rsivanov commented 4 years ago

IMessageBus isn't present anymore in a modern version of SignalR, which is SignalR for asp.net core, but the idea is still the same - to inject an IBus into a custom implementation of HubLifetimeManager to use any supported Rebus transport as a backplane. A reference implementation of this idea in MassTransit - https://github.com/MassTransit/MassTransit/blob/develop/src/MassTransit.SignalR/MassTransitHubLifetimeManager.cs

markusgud commented 4 years ago

Great idea. This is definitely something we could use.

rsivanov commented 4 years ago

@mookid8000 I could try to help with the implementation of Rebus.SignalR :). All I need for that - is an empty repository (maybe with some standard license files and build scripts as in other Rebus repos) to make a fork of and then to submit a pull request to.

mookid8000 commented 4 years ago

@rsivanov cool! I made one here 👉 https://github.com/rebus-org/Rebus.SignalR

It follows the same structure as most other Rebus integrations, so it can insert extension methods into the Rebus.Config namespace, while keeping all of its own public stuff properly namespaces beneath Rebus.SignalR.... that might not be necessary for this repository though, because I'm not sure it will need to provide extensions for Rebus' configuration.... but I guess you'll figure out out along the way.

Feel free to push work my way, if there's something on the Rebus side of things I can help with 🙂

rsivanov commented 4 years ago

@mookid8000 Could you please take a look at https://github.com/rebus-org/Rebus.Async/pull/11? I need to use that library for the implementation of Rebus.SignalR backplane, and it wasn't yet updated to Rebus 6.0

mookid8000 commented 4 years ago

Sure..... but one quick question though: What do you need Rebus.Async for?

rsivanov commented 4 years ago

Sure..... but one quick question though: What do you need Rebus.Async for?

There's a AddToGroupAsync(string connectionId, string groupName, CancellationToken cancellationToken = default) method in HubLifetimeManager interface that should guarantee, that after return from this call we added a specified connection to a group. That connection lives on some host (doesn't have to be the current one), so we need to make a request to that host through the backplane and wait for a reply. The same idea is implemented in Masstransit.Signalr:

RequestHandle<GroupManagement<THub>> request =
                    _groupManagementRequestClient.Create(new {ConnectionId = connectionId, GroupName = groupName, ServerName, Action = GroupAction.Add},
                        cancellationToken);

Response<Ack<THub>> ack = await request.GetResponse<Ack<THub>>().ConfigureAwait(false);
{ack.Message.ServerName}.");

In Rebus world we have Rebus.Async that allows to wait for a reply, but it needs to be extended to support Publish and wait for a reply from some subscriber in addition to Send and wait for a reply. I'm sorry, that I forgot to include the Publish part into an initial pull request to Rebus.Async. It's in https://github.com/rebus-org/Rebus.Async/pull/12

rsivanov commented 4 years ago

@mookid8000 Hi! I sent you a pull request with the implementation of Rebus.SignalR with integration tests and a sample application. Everything seems to be working well so far :) https://github.com/rebus-org/Rebus.SignalR/pull/1

mookid8000 commented 4 years ago

Thanks to @rsivanov Rebus.SignalR is now a thing! 👉 https://github.com/rebus-org/Rebus.SignalR

It's available on NuGet.org as Rebus.SignalR 0.0.2 atm 😃

ryanbuening commented 4 years ago

You wouldn't need to use a separate backplane like Redis, if you already have Rebus (possibly backed by RabbitMq) in your infrastructure.

Should this work if we have Rebus backed by SqlServer and not RabbitMq?

mookid8000 commented 4 years ago

This should work with any transport supported by Rebus. So yes, it should work with SQL Server, RabbitMQ, Amazon SQS, etc. 🙂