I would like to ask is there for MassTransit to notify the client application on RabbitMQ connection state change. I checked IBusObserver, but there is not information when MassTransit disconnects with RabbitMQ.
This is an important function because, in case of disconnection and reconnection, I have to send a message with the current state of the application.
You need to use the IReceiveEndpointObserver instance instead.
Here is an example of how it can be done, what MassTransit does to support ASP.NET Core health checks: https://github.com/MassTransit/MassTransit/blob/develop/src/Containers/MassTransit.AspNetCoreIntegration/HealthChecks/ReceiveEndpointHealthCheck.cs
You attach the observer when configuring the endpoint:
Bus.Factory.CreateUsingRabbitMq(cfg =>
{
// host and other things
...
cfg.ReceiveEndpoint("my_endpoint", ep =>
{
// consumers
...
ep.ConnectReceiveEndpointObserver(observer);
}
}
Related
I am writing a worker service in Net core 6 and I want to call the worker service from API and pass sone data to worker service.
My Worker service code is as below:
``
IHost host = Host.CreateDefaultBuilder(args)
.UseWindowsService(options =>
{
options.ServiceName = "TestWindowService";
})
.ConfigureServices(services =>
{
services.AddHostedService<ServiceWorker>();
services.AddTransient<ITestService, TestService>();
services.AddTransient<IDatabaseClientService, DatabaseClientService>();
})
.Build();
await host.RunAsync();
``
I am calling Worker service from API and want to pass some data to Worker Service:
I tried this code from API but it is not working:
``
ServiceController service = new ServiceController();
service.MachineName = ".";
service.ServiceName = this.WindowServiceName;
if (service.Status != ServiceControllerStatus.Running)
service.Start(new string[] { "Testargs" });
``
How can I pass data from API to worker service? I tried the above code, but it is not working.
Once the service is running then I want to pass data to it again.
You should use a message queue, such as Azure Storage Queues / Amazon Simple Queue Service / Google Cloud Tasks. On-premise solutions also exist, such as Kafka.
The idea is that the API serializes a message and sends it to the message queue before returning an HTTP response. The background service reads from that queue and handles those messages. I have more information about this pattern in my blog posts on basic distributed architecture and queues in particular.
Our Azure SignalR application is a bit of a hybrid, outgoing messages go into ActiveMQ then get picked up by a listener in a hosted service that receives them and sends them to the NotificationsHub (in the same API project). e.g. await _notificationsHub.Clients.All.SendAsync("PerformAction", action, payload);
Recently I tried to extend this so that a second application using a different authentication scheme (this one is external facing, the existing one is internal facing) could connect and receive some messages (and send others back). I did a POC and everything seemed fine.
public class NotificationsHub : Microsoft.AspNetCore.SignalR.Hub {
public override async Task OnConnectedAsync() {
await Groups.AddToGroupAsync(Context.ConnectionId, "foo");
await base.OnConnectedAsync();
await Clients.Caller.SendAsync("SetConnectionId", Context.ConnectionId);
}
}
Today I was debugging in Visual Studio the new application API and in the Hub's OnConnectedAsync method I kept receiving the "connected" events for users on a completely different server.
So my question is, does SignalR fire the "OnConnected" event for every hub connected to the same endpoint (for every instance of that hub)?
Even if that is the case wouldnt these two Hub classes be considered separate and not share their groups (see multiple hubs)?
Edit
For reference the project is targeting netcoreapp3.1, and using Microsoft.Azure.Signalr 1.8.1 in the original project and 1.16.1 in the new one.
It turns out that SignalR uses the name of the "Hub" class when connecting to the Azure SignalR service, i.e. 'wss://foo.service.signalr.net/server/?hub=notificationshub&cid={guid}'.
All hubs with the same name are treated as the same hub. I couldnt find that in the docs anywhere but it is implied in ApplicationName property of ServiceOptions which says "Gets applicationName, which will be used as a prefix to apply to each hub name"
My application is having issues accepting the handshake about half the time in my production environment. On my local machine and in my staging environment, which is the same as production, it works every time.
It is a .Net Core 2.1 app using aspnet-signalr/1.1.4
I am not configuring SignalR to use any specifics in my startup.s
app.UseSignalR(routes => { routes.MapHub<PortfolioHub>("/loadpagedetailsjob"); });
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Dashboard}/{action=Index}/{id?}");
});
my PortfolioHub is just a direct implementation of the Hub class
and in my page
var connection = new signalR.HubConnectionBuilder()
.withUrl('/loadpagedetailsjob')
.configureLogging(signalR.LogLevel.Information)
.build();
connection.start().then(function () {
connection.invoke("Subscribe");
});
It looks like it tries to negotiate web socket then long polling and both fail. But the requests return 200
Since it is only happening sometimes I am having issues resolving the issue. My only suspicion at this point is since my environment is in AWS behind a load balance that the negotiate requests are routed to different servers which might cause the issue?
Any help is appreciated.
SignalR requires that one connection is always handled by the same server. The typical solution is to configure the load balancer to use sticky sessions. With sticky sessions enabled, the load balancer will route requests of the same user to the same backend server.
https://learn.microsoft.com/en-us/aspnet/core/signalr/scale?view=aspnetcore-3.1
Let say i have a android app installed on app and user has subscribed to many topic. Now if user uninstalled app
how can I remove all user specific subscribed topic from broker ?
Can i unsubscribe paho JS client subscribe topics using paho Java client ?
In JS side this is how i am connecting and subscribing to my broker
client.connect({
userName:user,
password:password,
onSuccess:onConnect,
onFailure:onFailure,
'willMessage': willMessage
});
var onConnect = function(frame) {
client.subscribe("user/"+clientId+"/msg");
};
OK, if your not setting cleanSession to false then subscriptions shouldn't be persisted.
But it sounds like you're looking for something similar to mosquitto's persistent_client_expiration option which says how long to keep this information after a clients last connection.
Not sure if rabbitmq has a similar option
The reason I'm writing this question is that I seem to be getting the following error when I'm trying to communicate between a windows service and a WPF app via a WCF service with a NetNamedPipe binding:
System.ServiceModel.EndpointNotFoundException: There was no endpoint
listening at net.pipe://localhost/Pipe_SendInfo
Now the gory details.
Ok, I have a windows service that is periodically executing code, I wanted to let a user know what is happening inside the service. So I read that I could accomplish this via NetNamedPipe WCF service. I created two test apps and successfully was able to send a message from one process to another. I then attempted to send messages from the windows service to a client app(on the same machine) and have so far failed miserably :(.
My windows service essentially does this(trying to send info):
ChannelFactory<SkipSyncLib.ISendInfo> pipeFactory =
new ChannelFactory<SkipSyncLib.ISendInfo>(
new NetNamedPipeBinding(),
new EndpointAddress("net.pipe://localhost/Pipe_SendInfo"));
pipeFactory.CreateChannel();
pipeFactory.SendInfo(info);
and the application that is supposed to receive the information does this when it starts up:
public void Start()
{
HostService = new ServiceHost(this, new Uri[] { new Uri("net.pipe://localhost") });
HostService.AddServiceEndpoint(typeof(ISendInfo), new NetNamedPipeBinding(), "Pipe_SendInfo");
try
{
HostService.Open();
}
catch (Exception exc)
{
//Error handling
}
}
The kicker is that while the windows service is failing miserably to find the endpoint I have another console app that is able to send info to the running client app successfully. So logic would tell me that it probably has something to do with users. But I can't figure it out.
Any ideas? Should I just drop named pipes and go with an http binding?
I just found out about named pipes earlier today so please be gentle if the answer is obvious.
Thanks
I figured out a way for it to work. There's probably a more elegant way to do this, but if the windows service and the client app are run as the same user then the communication channel works.
Should you use the same endpoint address?
HostService = new ServiceHost(this, new Uri[] { new Uri("net.pipe://localhost/Pipe_SendInfo") });
add /Pipe_SendInfo in Uri