I have created a wcf service, but when i am installing it on server, it is not picking the code.
Here is my program.cs class:
log4net.Config.XmlConfigurator.Configure();
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
and here is my service1.cs:
public Service1()
{
logger.Info("log started");
InitializeComponent();
}
protected override void OnStart(string[] args)
{
logger.Info("Service Started");
timerHandlingFirst.Elapsed += new ElapsedEventHandler(OnElapsedTimeFirst);
timerHandlingFirst.Enabled = true;
timerHandling.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timerHandling.Enabled = true;
}
I have attached used log4net dll, but its not even generating the logs.
Related
I am writing a Windows service using Topshelf that should start a self hosted webapi project and a FIX service based on quickfix/n. Please consider the shortened code below, which works so far.
However there is one problem - there are now two container instances living in my application. My guts tell me this is a bad idea, especially because I am loading MyBigModule two times. Also because one of my controllers require the same component than the one using quickfix.
// Assembly A referencing B
public class Program
{
public static void Main(string[] args)
{
var builder = new ContainerBuilder();
buider.RegisterModule<MyBigModule>();
var container = builder.Build();
_ = HostFactory.Run(c =>
{
c.UseAutofacContainer(container);
c.Service<IMyServiceManager>(svc =>
{
svc.ConstructUsingAutofacContainer();
// ...
}
// ...
});
}
}
// Assembly B
public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly())
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// ...
app.UseAutofacMiddleware(container);
app.UseAutofacWebApi(config);
app.UseWebApi(config);
}
}
// Assembly B
public class WebHost : IWebHost
{
// ...
public void Start()
{
WebApp.Start<Startup>("someUrl");
}
}
// Assembly B
public class MyBigModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register<WebHost>.As<IWebHost>();
// ...
}
}
My first approach was to pass an Action<IAppBuilder> to the WebHost constructor, that is created within Main(). Something like this:
public class Program
{
public static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.RegisterModule<MyBigModule>();
var container = builder.Build();
var webhost = new WebHost("someUrl", app =>
{
var config = new HttpConfiguration();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// ....
});
builder.RegisterInstance(webost);
// ...
}
}
However I would have to build my container first and then add another registration later. Which doesn't follow the recommendation that a container should be considered immutable. Another alternativ would be to pass the container instance down to my WebHosts Startup class.
It seems that I need to have a registration of my container inside the container itself. How would I do that? Maybe there is a better approach? I hope it's clear what I am struggling with.
I am pretty sure there must be a better way to wire up webapi's resolver. Any ideas and feedback is very appreciated.
I solved it in the meantime, thanks to this post. We can inject an instance of ILifetimeScope to the constructor without having to register anything.
// Assembly A referencing B
public class Program
{
public static void Main(string[] args)
{
var builder = new ContainerBuilder();
buider.RegisterModule<MyBigModule>();
var container = builder.Build();
_ = HostFactory.Run(c =>
{
c.UseAutofacContainer(container);
c.Service<IMyServiceManager>(svc =>
{
svc.ConstructUsingAutofacContainer();
// ...
}
// ...
});
}
}
// Assembly B
public class WebHost : IWebHost
{
private readoly ILifetimeScope scope
public WebHost(ILifetimeScope scope)
{
this.scope = scope;
}
public void Start()
{
WebApp.Start("someUri", app => {
var config = new HttpConfiguration
{
DependencyResolver = new AutofacWebApiDependencyResolver(this.scope)
};
// ...
});
}
}
// Assembly B
public class MyBigModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register<WebHost>.As<IWebHost>();
// ...
}
}
We're building a WCF server (.NET 4.5). It will only use net.pipe transport.
When a client closes the PIPE connection, the server gets unhandled CommunicationException, and terminates.
Q1. How do I handle the CommunicationException so the server does not terminate and continues serving other clients?
Q2. In the handler, how do I get SessionId of the session that was aborted? I need this to do clean up some session-specific data.
Thanks in advance!
contract
[ServiceContract(CallbackContract = typeof(IContractCallback))]
public interface IContractServer
{
[OperationContract(IsOneWay = true)]
void Connect(bool status);
[OperationContract(IsOneWay = false)]
void Disconnect(IContractServer _channelCallback);
[OperationContract(IsOneWay = true)]
void Play(bool status);
}
service
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class Service : IContractServer
{
public List<IContractCallback> _channeList = new List<IContractCallback>();
public void Connect(bool status)
{
IContractCallback a = OperationContext.Current.GetCallbackChannel<IContractCallback>();
int call = 0;
foreach (var callBack in _channeList)
{
if (callBack == a)
{
call++;
}
}
if (call == 0)
{
_channeList.Add(a);
a.ConnectCallback(true);
}
else
{
a.ConnectCallback(false);
}
}
public void Disconnect(IContractServer _channelCallback)
{
foreach (var contractCallback in _channeList)
{
if (contractCallback == _channelCallback)
{
_channeList.Remove(contractCallback);
}
}
}
public void Play(bool status)
{
foreach (var contractCallback in _channeList)
{
contractCallback.PlayCallback(status);
}
}
}
client
using System.ComponentModel;
using System.ServiceModel;
using System.Windows;
using Host;
namespace VideoPlayer
{
public partial class MainWindow : Window, IContractCallback
{
private IContractServer Proxy = null;
public MainWindow()
{
InitializeComponent();
InstanceContext context = new InstanceContext(this);
DuplexChannelFactory<IContractServer> factory = new DuplexChannelFactory<IContractServer>(context, new NetNamedPipeBinding(), "net.pipe://localhost");
Proxy = factory.CreateChannel();
Proxy.Connect(true);
}
public void ConnectCallback(bool status)
{
MessageBox.Show(status ? "connected" : "no connected");
}
public void PlayCallback(bool status)
{
if (status)
{
MessageBox.Show("status true");
}
else
{
MessageBox.Show("status false");
}
}
private void ButtonPlay(object sender, RoutedEventArgs e)
{
Proxy.Play(true);
}
private void MainWindow_OnClosing(object sender, CancelEventArgs e)
{
//хочу отправить сообщение о закрытии
Proxy.Disconnect(Proxy);
}
I faced with this problem before in my duplex services when an event raised from server side the exception occurred if there was no alive channel between client and server so server dropped to Fault state and all next requests won't be responded,
For this reason I came to this conclusion to check the channel and if it was alive then let call back methods to be raised.
In service side the trick would be like ↓
bool IsChannelAlive()
{
Logging logging = new Logging(LogFile);
try
{
if (((ICommunicationObject)_callbackChannel).State == CommunicationState.Opened)
{
logging.Log(LoggingMode.Prompt, "Channeld is still alive, can raise events...");
return true;
}
}
catch (Exception exp)
{
logging.Log(LoggingMode.Error, "IsChannelAlive()=> failed, EXP: {0}", exp);
}
logging.Log(LoggingMode.Warning, "Channeld is not alive so events won't raised...");
return false;
}
and in one of my events I use it like :
void stran_OperationTimedOut(object sender, EventArgs e)
{
if (IsChannelAlive())
_callbackChannel.OnOperationTimedOut();
}
But for a while I use this trick to know closed channel to do something:
public ImportService()
{
//Handle ContextClose to Audit all actions made in session
OperationContext.Current.InstanceContext.Closed += delegate
{
//Here
};
}
which is not reliable.
I am still using that IsAliveChannel() in my services.
Hope this answer resolve your problem or give you the clue.
I have two web api.
One publish a message when specific controller be call (work)
One subscribe to receive message. (not work)
Here is config for both web api :
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddRawRabbit();
var builder = new ContainerBuilder();
builder.RegisterRawRabbit("guest:guest#localhost:15672/");
var container = builder.Build();
}
In web api 1, here is action that publish a message :
[Route("api/[controller]")]
public class ValuesController : Controller
{
// GET api/values
[HttpGet]
public IEnumerable<string> Get()
{
EventMessage message = new EventMessage() ;
var client = BusClientFactory.CreateDefault();
message = new EventMessage() { id = new Guid(), createDate = DateTime.Now };
client.PublishAsync<EventMessage>(message);
Console.WriteLine($"message create {message.ToString()}");
return new string[] { "value1", "value2",};
}
}
And in web api 2, I dont know how to receive that message,
here is the way that i try but it not work
public class Listener
{
public static void Start()
{
var client = BusClientFactory.CreateDefault());
client.SubscribeAsync<EventMessage>(async (msg, context) => Console.WriteLine($"Recieved:{msg.createDate.ToString()}.");
}
}
public class Program
{
public static void Main(string[] args)
{
//not working
Listener.Start();
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
In this project, im using Rawrabbit, any library with the same scenario will be ok. Thanks
Update: i fix this code, it work
I have a MVC4 .Net web application on 3-tier architecture with Unity dependency injection, and I want to shedule everyday a verficiation and send some mails where is the case. For this I want to use Quartz Scheduler in Application_start, because of the dependency injection windows service is not a good option.
Here is my code in application_start.
// construct a scheduler factory
ISchedulerFactory schedFact = new StdSchedulerFactory();
IScheduler sched = schedFact.GetScheduler();
sched.Start();
IJobDetail dailyUserMailJob = new JobDetailImpl("DailyUserMailJob", null, typeof(SchedulerJob));
// fire every time I open App/EveryDay
ITrigger dailyUserMailTrigger = new SimpleTriggerImpl("DailyUserMailTrigger", 1,
new TimeSpan(1, 0, 0, 0));
sched.ScheduleJob(dailyUserMailJob, dailyUserMailTrigger);
Here is my job code :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using EvaluationMvc.Bll.Contracts;
using Quartz;
using Quartz.Impl;
namespace EvaluationMvc.Utils
{
public class SchedulerJob : IJob
{
private IEvaluationBus _iEvaluationBus;
public SchedulerJob(IEvaluationBus iEvaluationBus)
{
//Dependency injection
_iEvaluationBus = iEvaluationBus;
}
public void Execute(IJobExecutionContext context)
{
_iEvaluationBus.testingArchitecture();
// Sends a test mail.
}
}
}
However my job is never executed, what could be the problem ?
Quartz.net Scheduler must be created as singleton.
You can install Unity.MVC4 NuGet Package.
It will create a Bootstrapper class which should look something like this:
public static class Bootstrapper
{
public static IUnityContainer Initialise()
{
var container = BuildUnityContainer();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
return container;
}
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
// Register your interfaces here.
RegisterTypes(container);
return container;
}
public static void RegisterTypes(IUnityContainer container)
{
}
}
Then you have to create your own implementation of JobFactory. This article might help you and this one is worth reading:
public class UnityJobFactory: IJobFactory
{
private readonly IUnityContainer container;
static UnityJobFactory()
{
}
public UnityJobFactory(IUnityContainer container)
{
this.container = container;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
var jobDetail = bundle.JobDetail;
var jobType = jobDetail.JobType;
try
{
return this.container.Resolve(jobType) as IJob;
}
catch (Exception ex)
{
throw new SchedulerException(string.Format(
CultureInfo.InvariantCulture,
"Cannot instantiate class '{0}'", new object[] { jobDetail.JobType.FullName }), ex);
}
}
public void ReturnJob(IJob job)
{
// Nothing here. Unity does not maintain a handle to container created instances.
}
}
and your own implementation of StdSchedulerFactory:
public class UnitySchedulerFactory : StdSchedulerFactory
{
private readonly UnityJobFactory unityJobFactory;
public UnitySchedulerFactory(UnityJobFactory unityJobFactory)
{
this.unityJobFactory = unityJobFactory;
}
protected override IScheduler Instantiate(QuartzSchedulerResources rsrcs, QuartzScheduler qs)
{
qs.JobFactory = this.unityJobFactory;
return base.Instantiate(rsrcs, qs);
}
}
Going back to your Unity Bootstrapper you have to register your interfaces:
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
container.RegisterType<ISchedulerFactory, UnitySchedulerFactory>(new ContainerControlledLifetimeManager());
container.RegisterType<IScheduler>(new InjectionFactory(c => c.Resolve<ISchedulerFactory>().GetScheduler()));
container.RegisterType<IQuartzScheduler, QuartzScheduler>(new ContainerControlledLifetimeManager());
container.RegisterType<IEvaluationBus, EvaluationBus>();
RegisterTypes(container);
return container;
}
I've wrapped up my service scheduler in a class so that I can create it singleton:
public interface IQuartzScheduler
{
void Run();
void Stop();
}
and:
public class QuartzScheduler : IQuartzScheduler
{
private readonly ISchedulerFactory SchedulerFactory;
private readonly IScheduler Scheduler;
public QuartzScheduler(ISchedulerFactory schedulerFactory, IScheduler scheduler)
{
this.SchedulerFactory = schedulerFactory;
this.Scheduler = scheduler;
}
public void Run()
{
IJobDetail dailyUserMailJob = new JobDetailImpl("DailyUserMailJob", null, typeof(Scheduler.SchedulerJob));
// fire every time I open App/EveryDay
ITrigger dailyUserMailTrigger = new SimpleTriggerImpl("DailyUserMailTrigger", 10,
new TimeSpan(0, 0, 0, 20));
this.Scheduler.ScheduleJob(dailyUserMailJob, dailyUserMailTrigger);
this.Scheduler.Start();
}
public void Stop()
{
this.Scheduler.Shutdown(false);
}
}
As you can see in this class I'll create my jobs/trigger and start the scheduler.
now in your Application_Start (global.asax) you can "bootstrap" your Unity Container, get the service scheduler and run it.
var unityContainer = Infrastructure.Bootstrapper.Initialise();
unityContainer.Resolve<IQuartzScheduler>().Run();
You can find a working sample following this link (QuartzWithUnity).
Very useful, thanks LeftyX. I think, in Application_Start you have to create servise like this:
var unityContainer = Bootstrapper.Initialise();
QuartzScheduler jobService = (QuartzScheduler)unityContainer.Resolve(typeof(QuartzScheduler), "Jobs");
jobService.Run();
I'm trying to run this example derived from this blog entry on
WCF Tutorial - Basic Interprocess Communication
If I run the server code in .NET4, it throws the following exception:
First-chance exception at 0x754cd36f (KernelBase.dll) in TestConsole.exe: 0xE0564552: 0xe0564552.
If I run the server code in .NET3.5, it works just fine. Client code is compiled against .NET4 in both tests. My server code is as follows:
[ServiceContract]
public interface IStringReverser
{
[OperationContract]
string ReverseString(string value);
}
public class StringReverser : IStringReverser
{
public string ReverseString(string value)
{
char[] retVal = value.ToCharArray();
int idx = 0;
for (int i = value.Length - 1; i >= 0; i--)
retVal[idx++] = value[i];
return new string(retVal);
}
}
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(StringReverser), new Uri[] { new Uri("net.pipe://localhost") }))
{
host.AddServiceEndpoint(typeof(IStringReverser), new NetNamedPipeBinding(), "PipeReverse");
host.Open();
Console.WriteLine("Service is available. Press <ENTER> to exit.");
Console.ReadLine();
host.Close();
}
}
}
My client code is as follows:
[ServiceContract]
public interface IStringReverser
{
[OperationContract]
string ReverseString(string value);
}
class Program
{
static void Main(string[] args)
{
ChannelFactory<IStringReverser> pipeFactory =
new ChannelFactory<IStringReverser>(
new NetNamedPipeBinding(),
new EndpointAddress(
"net.pipe://localhost/PipeReverse"));
IStringReverser pipeProxy = pipeFactory.CreateChannel();
while (true)
{
string str = Console.ReadLine();
Console.WriteLine("pipe: " +
pipeProxy.ReverseString(str));
}
}
}
Why on earth is this failing on .NET4? Seems like a pretty basic example. I did do a clean/build between each run. Here is a snapshot of the actual stacktrace:
It turns out I had the "throw" checked in Debug -> Exceptions -> C++ Exceptions while in Visual Studio. If I don't throw the exception, but let it be handled, everything works fine.