Changing which queues are used for NServiceBus Pub/Sub scenario - nservicebus

I'm new to NServiceBus and I'm trying to use it with IIS and SignalR. I have a working scenario but I'm curious how the client chooses which queues to publish to. I've noticed (by stopping IIS and running the publisher) that the message gets published to a system.web queue. I assume this is because my endpoint is being started by ASP.Net or something similar. However, this seems like a really generic queue to use and I would like to use application specific queue names. How do I specify which queues the publisher uses? I've changed the endpoint on the SignalR application but it doesn't seem to make much of a difference.
Here is my client config:
[EndpointName("signalbus.web")]
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server
{
}
Here is my app.config from the publisher:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="MessageForwardingInCaseOfFaultConfig" type="NServiceBus.Config.MessageForwardingInCaseOfFaultConfig, NServiceBus.Core" />
<section name="TransportConfig" type="NServiceBus.Config.TransportConfig, NServiceBus.Core"/>
<section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
</configSections>
<connectionStrings>
<add name="NServiceBus/Persistence" connectionString="Url = http://localhost:9090" />
</connectionStrings>
<MessageForwardingInCaseOfFaultConfig ErrorQueue="error" />
<TransportConfig MaximumConcurrencyLevel="5" MaxRetries="2" MaximumMessageThroughputPerSecond="0"/>
<UnicastBusConfig>
<MessageEndpointMappings>
<add Messages="SignalBus.Messages" Endpoint="signalbus.web" />
</MessageEndpointMappings>
</UnicastBusConfig>
</configuration>

When you configure the bus:
Configure.With().DefineEndpointName("MyAppName")
Edit
I'm a little confused based on your posted code and your comments. Are you hosting the subscriber in IIS/ASP.Net? If so, I think EndpointConfig will get ignored, as (AFAIK) it is only used via the NSB Host.
See this link for configuring the Bus in your own process (or ASP.Net):
http://docs.particular.net/nservicebus/hosting-nservicebus-in-your-own-process-v4.x
Also, you shouldn't need to reference the subscriber endpoint in your publisher's config--it needs no knowledge of its subscribers. It gets that via RavenDB or whatever subscription storage you are using.

Related

how to restart Hangfire server after reboot server IIS 8.5

I created a webapp with blazor serverside with a scheduler in my app using Hangfire. It's hosted in a IIS 8.5 on windows server 2012.
I already did all the settings to make sure my blazor app dont stop and dont recycle (idle=0,startmode,Regular Time Interval...) so the sheduler is always running. And all work good.
But if there is any server reboot, i need to restart my Hangfire server to restart the sheduler inside the app (just with single ping of the url in a browser)...
Like we can see on the screen, the hangfire server dont start until i ping my blazor's URL in a browser...
So you implemented all steps outlined in the hangfire documentation including preload and applicationInitialization?
Step 5 is persisted in the web.config of your application. To make sure it is not overwritten on deployment, one can put a web.config with the respective configuration under source control.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
<!-- Add this node to web.config -->
<applicationInitialization doAppInitAfterRestart="true">
<!-- Only needed when website contains multiple child apps -->
<add initializationPage='/hangfire',hostname='' />
<applicationInitialization />
</system.webServer>
</configuration>
Finally, if you use the app_offline.htm during deployment either directly or indirectly through the Azure DevOps Pipelines deploy task, then after the app_offline.htm is removed, only the next request restarts the app. In that case you need to fire a warm-up request manually. You can use a more elaborate warm-up script or this one-liner in your deployment pipeline.
curl https://my-page.com/
I think this is primarily an IIS thing, and what you want is to set the Application Pool in IIS to AlwaysRunning, so instead of starting up the worker process on the first web request it starts the worker process as soon as IIS starts.
See this SF answer

MVC Entity framework from local database to SQL database Azure

Possibly a very simple question, but it has already taken me several days. The problem:
In my project, MVC Entity framework, and on my local computer it connects with a local database and that works as expected. I can add items to the database and remove its etc. At azure, I have a SQL database and when I deploy the project to azure I get the following error message
network-related or instance-specific error occurred while establishing a
connection to SQL Server. The server was not found or was not accessible.
Verify that the instance name is correct and that SQL Server is configured to
allow remote connections. (provider: SQL Network Interfaces, error: 52 -
Unable to locate a Local Database Runtime installation. Verify that SQL
Server Express is properly installed and that the Local Database Runtime
feature is enabled.)]
I ques that the my connection string is incorrectly and my application can't connect to the azure SQL database. I tried to add and change the connection string, but somehow I can't make it work. This is what I have (minus password and username) :
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<connectionStrings><add name="InventoryEntities" connectionString="metadata=res://*/Administration.csdl|res://*/Administration.ssdl|res://*/Administration.msl;provider=System.Data.SqlClient;provider connection string="Server=tcp:****.database.windows.net,1433;Initial Catalog=****;Persist Security Info=False;User ID=****;Password=****;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"" providerName="System.Data.EntityClient" /></connectionStrings>
</configuration>
What am I doing wrong?
After a night sleep, I finally got it working.First of all, I had to make clear which database I was going to be use where the DbContext was initialized
public class EFDbContext : DbContext
{
public EFDbContext() : base("name=InventoryEntities")
{
}
}
With InventoryEntities being the name of the connectionstring in the web.config of the WebUI which I did not change.
Simple as that, but it took days......

Merge wcf app.config with another config file another project?

I have a MyProject.config file that contains ConnectionStrings, AppSettings, and custom sections. I don't want to have to duplicate these settings in the wcf app.config file. Is it possible to merge MyProject.config with app.config or web.config if it is hosted in IIS. If so, where in the code would I do this and how would it be done?
As an example, in MyProject.config, I have a section group called Common and in Common I have AppSettings and ConnectionStrings. I know I can duplicate this in app.config, but then I would have to maintain it in two places.
MyProject.config:
<?xml version="1.0"?>
<configuration>
<sectionGroup name="common">
<section name="appSettings" />
<section name="connectionStrings" />
</sectionGroup>
</configSections>
<common>
<appSettings>
<add key="UserName" value="test" />
<add key="Password" value="test" />
</appSettings>
<connectionstrings></connectionstrings>
</common>
app.config for wcf contains ServiceModel configuration, I dont' want to have to put the above in app.config. I want to read it, does this make sense?
WCF will only load the config based settings for a service from the .NET configuration file for an application (web.config for IIS hosted services). Essentially you are fighting the .NET configuration file model.
If you want to keep the files separate then decide what will act as your primary config file and then use the configSource model for combining multiple config files

Publisher messages not reaching subscriber

Publisher config
<!-- 1. In order to configure remote endpoints use the format: "queue#machine"
2. Input queue must be on the same machine as the process feeding off of it.
3. Error queue can (and often should) be on a different machine.
4. The community edition doesn't support more than one worker thread.
-->
<MsmqTransportConfig
InputQueue="HomeOfficePublisherQueue"
ErrorQueue="error"
NumberOfWorkerThreads="1"
MaxRetries="5"
UseJournalQueue="true"
/>
<DBSubscriptionStorageConfig>
<NHibernateProperties>
<add Key="connection.provider"
Value="NHibernate.Connection.DriverConnectionProvider"/>
<add Key="connection.driver_class"
Value="NHibernate.Driver.SqlClientDriver"/>
<add Key="connection.connection_string"
Value="Server=<dbserver>\corpdev;initial catalog=NServiceBus;Integrated Security=SSPI"/>
<add Key="dialect"
Value="NHibernate.Dialect.MsSql2005Dialect"/>
</NHibernateProperties>
</DBSubscriptionStorageConfig>
<UnicastBusConfig
DistributorControlAddress=""
DistributorDataAddress=""
ForwardReceivedMessagesTo="">
<MessageEndpointMappings>
</MessageEndpointMappings>
</UnicastBusConfig>
</configuration>
Subscriber config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="MsmqTransportConfig" type="NServiceBus.Config.MsmqTransportConfig, NServiceBus.Core" />
<section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
</configSections>
<!-- 1. In order to configure remote endpoints use the format: "queue#machine"
2. Input queue must be on the same machine as the process feeding off of it.
3. Error queue can (and often should) be on a different machine.
4. The community edition doesn't support more than one worker thread.
-->
<MsmqTransportConfig
InputQueue="VW_1140#<subscriberServer>"
ErrorQueue="error"
NumberOfWorkerThreads="1"
MaxRetries="5"
UseJournalQueue="true"
/>
<UnicastBusConfig>
<MessageEndpointMappings>
<add Messages="Message" Endpoint="HomeOfficePublisherQueue#<publisherServer>" />
</MessageEndpointMappings>
</UnicastBusConfig>
</configuration>
When i run pub and sub from diffrent machines, the messages from publisher don't reach subscriber. If I run them on the same machine they work fine.
=> the publisher is running on this machine and publisher queue is created locally.
is same as
=> the machine on which subscriber is running.
The profile is production and there is no exception in the log file.
Any clues why messages are getting dropped.
Thsnks for the help...
Check the internal outbound queue on the Publisher. If you see messages there this means it can't communicate with the Subscriber. This usually means that you may not have MSDTC running or the security for MSDTC is not correctly configured. Make sure you have "Allow Inbound" and "Allow Outbound" set in the MSDTC security settings.
I wanted to chuck my mouse at someone when I got mine working.
For me, the problem was that I was trying to send a plain poco class as my message.
app.config
<UnicastBusConfig ForwardReceivedMessagesTo="audit">
<MessageEndpointMappings>
<add Assembly="Messages" Endpoint="pub" />
</MessageEndpointMappings>
</UnicastBusConfig>
Then I thought maybe I need to tell what the object is supposed to be, so I configured the message as a message
Configure.With()
.DefiningMessagesAs(t => t.Namespace != null && t.Namespace.Contains("Messages"));
Still didn't work, so then for grins i changed it to this
Configure.With()
.DefiningEventsAs(t => t.Namespace != null && t.Namespace.Contains("Messages"));
Now it works fine

404 when running .net 4 WCF service on IIS (no svc file)

I'm testing out a REST service in WCF on .net 4 - i.e. no svc file. It works great when running against the VS dev server but when I switch it to run against IIS I get 404s when trying to browse the help page or hit any of the service methods.
I've dropped back to a bare bones service to just get it running on IIS but I'm not sure what's wrong with it.
The global.asax simply has
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(), typeof(DataPortalService)));
}
and the service itself is as simple as it gets:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class DataPortalService : IDataPortalService
{
[WebGet(UriTemplate = "Test/TestMethod")]
public string TestMethod()
{
return "Hi!";
}
}
[ServiceContract]
public interface IDataPortalService
{
[OperationContract]
string TestMethod();
}
and config file of
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" />
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
</configuration>
Hitting the /help page or the method gives me a 404.0.
I presume I'm just missing some setting in IIS to kick it in to life although it's a bit daft that it works fine on the dev server but not IIS.
Solved it after a dig around some other forums.
I initially added the following to my web config:
<system.webServer>
<handlers>
<remove name="svc-Integrated-4.0" />
<add name="svc-Integrated-4.0" path="*" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Clearly by default IIS doesn't know what to do with the extensionless requests and passed them on to the static file handler.
Given that MVC is using the same routine architecture I figured that the basic MVC site template must have some config in similar to the above since my MVC sites have worked fine when moved to IIS.
It turns out that they have a slightly different config and have the following entry instead:
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
Both configs seem to work ok but I settled on using the 2nd option in this case.
I had runAllManagedModulesForAllRequests="true" in my web.config but still couldn't get past the 404.0. Also tried installing "IIS 7 Recommended Configuration" without any luck. Rerunning aspnet_regiis solved the problem to me.
In the Run dialog box, type cmd, and then click OK.
At the command prompt, use the cd command to change the directory of the Aspnet_regiis.exe version you want to use. By default, Aspnet_regiis.exe is located in the following directory: systemroot\Microsoft.NET\Framework\versionNumber
Then run the following command: aspnet_regiis -ir
This will register "svc-Integrated-4.0" in the Handler Mappings.
HTTP 404 code can be returned also if you don't have some components of .NET framework installed.
There's for instance Windows Communication Foundation HTTP Activation feature in .NET Framework 3.5 and in .NET Framework 4.6 there are HTTP Activation, Message Queuing (MSMQ) Activation and a few more.
In Windows 10 these features aren't installed by default, so please keep in mind to take a look at Windows Features.
On IIS 5.1 on my machine, the .svc page was served only when I added HTTP Handler at Web Site level as well as virtual folder level. This should ideally work by inheritance!
Extention : .svc
Executable :
c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll