Deploy Hangfire distributed client/server

Hi everyone.
I want to deploy Hangfire as standalone service (windows service/console) but I can’t find any documentation.
Can you help me?
Thanks.

As a Service
http://docs.hangfire.io/en/latest/background-processing/processing-jobs-in-windows-service.html

As a Console Application
http://docs.hangfire.io/en/latest/background-processing/processing-jobs-in-console-app.html

Both are very straightforward to get started with. Maybe you have a more detailed question?

Thank you!
I have read two links but I don’t know how to from client connect to server.
I couldn’t find any document configuration or code?

You don’t need to connect the client and server, they should both have the same connectionstring and all communication is via the database.

Thanks.

So:

  1. I install Hangfire as standalone (window service/ console)
  2. I config same connection string in my Asp.net web application.

I don’t know from Asp.net website, If i want to Add job to queue, what could I do?
I reference DLL of Hangfire, and call API?

Thank you very much.

Exactly that. Let me show example:

You have a Console app for example, which references Hangfire.Core and Hangfire.SqlServer,

static void Main(string[] args)
    {
        GlobalConfiguration.Configuration.UseSqlServerStorage("HangfireDb");

        using (var server = new BackgroundJobServer())
        {
            Console.WriteLine("Hangfire Server started. Press any key to exit...");
            Console.ReadKey();
        }
    }

Here HangfireDb needs to be the key for a connectionstring in your app.config.

Then install Hangfire in your web app, using the usual method, but in your Startup class remove the line:

app.UseHangfireServer();

Now the server won’t be trying to complete process, just the console app.

Thank you very much.
So stupid I am.
Thank you :smile:

Apologies for re-hydrating an old question.

I’m trying to do the exact same thing as this and I’m having little success. I have the setup described as the OP, the problem I’m finding is that if I trigger recurring or background jobs on the dashboard from the client I am seeing errors. After some investigation It seems any job created or requested on the client fails - and never seems to hit the server (which is deployed on a remote machine). I have tried just setting up a simple background task from the client, like:

BackgroundJob.Schedule(() => Console.WriteLine("foo"), TimeSpan.FromSeconds(10));

This task, or hitting “trigger now” button on dashboard creates the same error, which is:

Newtonsoft.Json.JsonSerializationException

Error converting value "System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e" to type 'System.Type'. Path '[0]', line 1, position 107.

Newtonsoft.Json.JsonSerializationException: Error converting value "System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e" to type 'System.Type'. Path '[0]', line 1, position 107. ---> System.ArgumentException: Could not cast or convert from System.String to System.Type.
   at Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable(Object value, Type initialType, Type targetType)
   at Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast(Object initialValue, CultureInfo culture, Type targetType)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
   --- End of inner exception stack trace ---
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   at Hangfire.Storage.InvocationData.Deserialize()

If I add the app.UseHangfireServer() to the client (web app) it runs fine when its picked up from there. The server on the remote machine is set up as a console app at present.

EDIT: I have solved my issue. Phew. I am/was essentially running the web client and the console app server in different versions of .net. the web app being a netcoreapp1.0 and the console app running net461. I think what was happening was the serialisation of the method call was different across the two platforms - are therefore were not compatible, hence the json serialisation problem.

Hi Adam,

I did that same for my ASP.NET Core 2.0.
I added the following in ConfigureServices and I remove UseHangfireServer in Configure().

public void ConfigureServices(IServiceCollection services)
{
    services.AddHangfire(x => x.UseSqlServerStorage(Configuration.GetConnectionString("HangfireConnection")));
}

And I got error of

JobStorage.Current property value has not been initialized. You must set it before using Hangfire Client or Server API.

Services are lazy-initialized, and their initializers won’t execute unless you resolve them, e.g. by:

  • calling UseHangfireServer() in Configure()
  • calling UseHangfireDashboard() in Configure()
  • injecting IBackgroundJobClient into your controllers to schedule your jobs.
  • injecting IRecurringJobManager to manage your recurring jobs.

Just don’t use static methods in modern apps.

1 Like