I ran my program as BackgroundService but the service does not run the code - service

I've created program in C# Worker Service .NET 7.0. This program listening all incoming GET request and save this requests as URI and URL into Log.txt file. I used Titanium Web Proxy to listen all incoming requests from server. Program is working correctly but problem apear when im trying to run it as windows service. To do this im publishing my program into folder, next using command prompt Im creating service choosing .exe file from published folder and starting process with "sc start ServiceName" command. Service is running but its not working at all.
Here is my Program.cs code:
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
using Serilog.Extensions.Hosting;
using Serilog.Extensions.Logging;
namespace WorkerService5
{
public class Program
{
static async Task Main(string[] args)
{
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddHostedService<Worker>();
})
.UseWindowsService()
.UseSerilog()
.Build();
await host.RunAsync();
}
}
}
Here is my Worker.cs code:
using System.Net;
using Titanium.Web.Proxy;
using Titanium.Web.Proxy.EventArguments;
using Titanium.Web.Proxy.Models;
using Serilog;
using Microsoft.Extensions.Hosting;
namespace WorkerService5
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly IHostApplicationLifetime _hostApplicationLifetime;
public Worker(ILogger<Worker> logger, IHostApplicationLifetime hostApplicationLifetime)
{
_logger = logger;
_hostApplicationLifetime = hostApplicationLifetime;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken) => Task.Run(async () =>
{
try
{
var proxyServer = new ProxyServer(userTrustRootCertificate: false);
proxyServer.BeforeRequest += OnRequest;
var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true);
proxyServer.AddEndPoint(explicitEndPoint);
proxyServer.Start();
foreach (var endPoint in proxyServer.ProxyEndPoints)
_logger.LogInformation("Listening on '{0}' endpoint at Ip {1} and port: {2} ",
endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port);
proxyServer.SetAsSystemHttpProxy(explicitEndPoint);
// Console.ReadLine();
stoppingToken.Register(() =>
{
proxyServer.BeforeRequest -= OnRequest;
proxyServer.Stop();
});
await Task.Delay(Timeout.Infinite, stoppingToken);
}
catch (Exception)
{
throw;
}
});
private async Task OnRequest(object sender, SessionEventArgs e)
{
var filePath = #"E:\LogiusService\Logs\log.txt";
Log.Logger = new LoggerConfiguration()
.WriteTo.File(filePath, rollingInterval: RollingInterval.Day, shared: true)
.CreateLogger();
string requestedUrl = e.HttpClient.Request.Host;
Console.WriteLine("Requested URL: " + requestedUrl);
Log.Information($"Requested URL: " + requestedUrl);
string requestedUri = e.HttpClient.Request.RequestUri.AbsoluteUri;
Console.WriteLine("Requested URI: " + requestedUri);
Log.Information($"Requested URI: " + requestedUri);
}
}
}
Any ideas how can i run it as Windows Background Service?
Cheers!

Related

socket programming in c# with python

I am trying to run udp communication by running an external program (python script) in c # and opening the server as a thread.
When data is transfered to the port opened by the Python script, the server(c# program) receivce data.
But, there is no packet that is caught after some data has been sent.
Oddly enough, if i run directly a Python script by turning on the cmd from outside, It works well!
This Strange Phenomenon is observed just when I make python process run in c# program!
I Doubt that send buffer is the cause, but i don't know how to fix it.
I would really appreciate it if you helped me!
Here is my test code!
c# udp server
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Diagnostics;
namespace UdpSocket
{
public partial class Form1 : Form
{
bool used = true;
Thread t1 = null;
Process current_pro = null;
UdpClient srv = null;
public Form1()
{
InitializeComponent();
listView1.View = View.Details;
listView1.FullRowSelect = true;
listView1.GridLines = true;
listView1.Columns.Add("Timeline", 800, HorizontalAlignment.Center);
}
private void udpserverStart()
{
try
{
srv = new UdpClient(5582);
IPEndPoint clientEP = new IPEndPoint(IPAddress.Any, 0);
while (used)
{
byte[] dgram = srv.Receive(ref clientEP);
listView1.Items.Add(Encoding.Default.GetString(dgram));
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
finally
{
}
}
private void hookStart()
{
ProcessStartInfo proInfo = new ProcessStartInfo();
proInfo.FileName = "python.exe";
proInfo.Arguments = String.Format("-u {0}", #"output.py");
proInfo.CreateNoWindow = true;
proInfo.UseShellExecute = false;
proInfo.RedirectStandardInput = true;
proInfo.RedirectStandardOutput = true;
current_pro = new Process();
current_pro.StartInfo = proInfo;
current_pro.Start();
current_pro.Exited += (sender, e) =>
{
MessageBox.Show("Hook Process exited!");
};
}
private void button1_Click(object sender, EventArgs e)
{
t1 = new Thread(udpserverStart);
t1.Start();
hookStart();
}
private void button2_Click(object sender, EventArgs e)
{
used = false;
srv.Close();
//t1.Join();
t1.Abort();
current_pro.Kill();
this.Close();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
}
}
and python udp client
sc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sc.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 100000)
def message(message, data):
if message['type'] == 'send':
try:
payload = str(message['payload']) + '\n'
sc.sendto(payload.encode(), ('127.0.0.1', 5582))
print(str(message['payload']) + '\n')
except:
print('error');
elif message['type'] == 'error':
try:
print(str(message['stack']) + '\n')
except:
print('error');
else:
print("something...")
I just trying remove redirection code below, and it works well!
proInfo.RedirectStandardInput = true;
proInfo.RedirectStandardOutput = true;

Npgsql Performance

I am trying to implement Npgsql in our DAL and running into issues under heavy load. the following sample application is a decent representation of just a simple query that under heavy load, throws a 'A command is already in progress' exception. I am assuming this is due to the lack of MARS support so I also tried creating a connection each time with a using statement around each command only to have the performance become unusable. I checked that the username is indexed so that shouldn't be an issue.
Not sure what I am doing wrong here but I need some advice on how to get this performing well.
OS: Docker Container: microsoft/dotnet:2.1.301-sdk
using Npgsql;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Threading.Tasks;
namespace npgsqlTest
{
class Program
{
static async Task Main(string[] args)
{
DAL dal = new DAL();
dal.Prepare();
var tasks = dal.Users.Select(async user =>
{
Console.WriteLine(await dal.RunTest(user));
});
await Task.WhenAll(tasks);
}
}
public class DAL
{
private static string _ConnectionString;
private NpgsqlConnection _Connection;
public List<string> Users { get; set; } = new List<string>();
public DAL()
{
_ConnectionString = $"Host=192.168.1.1;Username=admin;Port=5432;Password=password;Database=BigDB;";
_Connection = new NpgsqlConnection(_ConnectionString);
_Connection.Open();
}
public void Prepare()
{
string query = "SELECT username FROM usertable;";
using (var cmd = new NpgsqlCommand(query, _Connection))
{
var reader = cmd.ExecuteReader();
using (reader)
{
while (reader.Read())
{
Users.Add(reader[0].ToString());
}
}
}
}
public async Task<string> RunTest(string user)
{
var parameters = new Dictionary<string, Object> { { "username", user } };
var query = $"SELECT name FROM usertable WHERE username = (#username);";
var reader = await QueryAsync(query, parameters);
using (reader)
{
if (reader.HasRows)
{
while (await reader.ReadAsync())
{
var name = reader["name"];
if (!(hash is DBNull))
return (string)name;
}
}
}
return String.Empty;
}
public async Task<DbDataReader> QueryAsync(string query, Dictionary<string, Object> parameters)
{
using (var cmd = new NpgsqlCommand(query, _Connection))
{
foreach (var parameter in parameters)
{
cmd.Parameters.AddWithValue(parameter.Key, parameter.Value == null ? DBNull.Value : parameter.Value);
}
cmd.Prepare();
return await cmd.ExecuteReaderAsync();
}
}
}
}

Problems with deploying Service Fabric project with Owin to Azure Service Fabric Cluster

I am working on a Service Fabric project with Owin, and I'm having troubles getting it deployed into the cloud. I have searched for others with the same problem, but I only found an answer telling that the error in the cluster tells where in the code it goes wrong. I have followed Microsofts Owin tutorial on how to write the method that fails, but with no luck.
I can run the project on Localhost direcly from Visual Studio, but the problem starts when I deploy it to a Service Fabric cluster in Azure. I have a 5 node cluster running, and when I deploy to it, it starts giving warnings after 2 minutes, and errors after 5 minutes. the status of the application is "inbuild".
Image of warning and Image of error.
I have two services, and the error from my cluster gives the error in these two methods(the same method in each service(OpenAsync)):
public Task<string> OpenAsync(CancellationToken cancellationToken)
{
var serviceEndpoint =
_parameters
.CodePackageActivationContext
.GetEndpoint("ServiceEndpoint");
var port = serviceEndpoint.Port;
var root =
String.IsNullOrWhiteSpace(_appRoot)
? String.Empty
: _appRoot.TrimEnd('/') + '/';
_listeningAddress = String.Format(
CultureInfo.InvariantCulture,
"http://+:{0}/{1}",
port,
root
);
_serverHandle = WebApp.Start(
_listeningAddress,
appBuilder => _startup.Configuration(appBuilder)
);
var publishAddress = _listeningAddress.Replace(
"+",
FabricRuntime.GetNodeContext().IPAddressOrFQDN
);
ServiceEventSource.Current.Message("Listening on {0}", publishAddress);
return Task.FromResult(publishAddress);
}
the error from the cluster tells the error is in this section:
_serverHandle = WebApp.Start(
_listeningAddress,
appBuilder => _startup.Configuration(appBuilder)
);
the other method(from the other service):
public Task<string> OpenAsync(CancellationToken cancellationToken)
{
var serviceEndpoint =
_parameters
.CodePackageActivationContext
.GetEndpoint("ServiceEndpoint");
var port = serviceEndpoint.Port;
var root =
String.IsNullOrWhiteSpace(_appRoot)
? String.Empty
: _appRoot.TrimEnd('/') + '/';
_listeningAddress = String.Format(
CultureInfo.InvariantCulture,
"http://+:{0}/{1}",
port,
root
);
try
{
_serverHandle = WebApp.Start(
_listeningAddress,
appBuilder => _startup.Configuration(appBuilder)
);
}
catch (Exception e)
{
Console.WriteLine(e);
throw e;
}
var publishAddress = _listeningAddress.Replace(
"+",
FabricRuntime.GetNodeContext().IPAddressOrFQDN
);
ServiceEventSource.Current.Message("Listening on {0}", publishAddress);
return Task.FromResult(publishAddress);
}
the error from the cluster tells the error is in this section:
try
{
_serverHandle = WebApp.Start(
_listeningAddress,
appBuilder => _startup.Configuration(appBuilder)
);
}
catch (Exception e)
{
Console.WriteLine(e);
throw e;
}
My StartUp Classes:
public void Configuration(IAppBuilder appBuilder)
{
var corsAttr = new EnableCorsAttribute(origins: "*", headers: "*", methods: "*");
var config = new HttpConfiguration();
config.WithWindsorSetup();
config.WithJsonSetup();
config.MapHttpAttributeRoutes(); //Enable Attribute-routing
config.WithSwaggerSetup();
config.EnsureInitialized();
config.EnableCors(corsAttr);
appBuilder.UseWebApi(config);
}
and where I create a new OwenCommunicationListener:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new[] {
new ServiceInstanceListener(initParams => new OwinCommunicationListener("", new Startup.Startup(), initParams))
};
}
I would very much like to be able to deploy it to Azure Service Fabric Cluster without any errors. Have a nice day, and thanks for helping.
you need to write your own custom class that configure the routing and http configuration for Owin listener.
Here is the class which I am using to configure the routing, try with it:
/// <summary>
/// This is the startup class that configure the routing and http configuration for Owin listener.
/// </summary>
public static class Startup
{
// This code configures Web API. The Startup class is specified as a type
// parameter in the WebApp.Start method.
public static void ConfigureApp (IAppBuilder appBuilder)
{
appBuilder.UseCors(CorsOptions.AllowAll);
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
config.Formatters.Remove(config.Formatters.XmlFormatter);
appBuilder.UseWebApi(config);
}
}
pass this class as an action to instance where you are creating instance of OwinCommunication Listener. Here is my code
endpoints.Select(endpoint => new ServiceInstanceListener(
serviceContext => new OwinCommunicationListener(Startup.ConfigureApp, serviceContext,
null, endpoint), endpoint));
This approach is working for me. Try with it hopefully it will work for you too
problem is solved. I edited this code:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return Context.CodePackageActivationContext.GetEndpoints()
.Where(endpoint => endpoint.Protocol.Equals(EndpointProtocol.Http) || endpoint.Protocol.Equals(EndpointProtocol.Https))
.Select(endpoint => new ServiceInstanceListener(serviceContext => new OwinCommunicationListener("", new Startup.Startup(), serviceContext)));
//return new[] {
// new ServiceInstanceListener(initParams => new OwinCommunicationListener("", new Startup.Startup(), initParams))
//};
}

How to host the Windows Workflow as a Web service(.svc)?

I am trying to host the windows workflow as a web service, below is the sample workflow that I built and would like to host as a web service(.svc), can you please suggest the required steps?
using System;
using System.ServiceModel.Activities;
using System.Activities;
using System.ServiceModel;
using System.Activities.Statements;
namespace DemoWF
{
public class _25_LeaveRequest
{
public WorkflowService GetInstance()
{
WorkflowService service;
Variable<int> empID = new Variable<int> { Name = "empID" };
Variable<int> requestID = new Variable<int> { Name = "requestID" };
Receive receiveLeaveRequest = new Receive
{
ServiceContractName = "ILeaveRequestService",
OperationName = "ApplyLeave",
CanCreateInstance = true,
Content = new ReceiveParametersContent
{
Parameters ={
{"empID",new OutArgument<int>(empID)}
}
}
};
SendReply replyLeaveRequestID = new SendReply
{
Request = receiveLeaveRequest,
Content = new SendParametersContent
{
Parameters ={
{"requestID",new InArgument<int>(requestID)},
},
},
};
Sequence workflow = new Sequence()
{
Variables = { empID, requestID },
Activities = {
new WriteLine{Text="WF service is starting..."},
receiveLeaveRequest,
new WriteLine{
Text=new InArgument<string>(aec=> "Emp ID="+empID.Get(aec).ToString())
},
new Assign<int>{
Value=new InArgument<int>(5),
To=new OutArgument<int>(requestID)
},
new WriteLine{
Text=new InArgument<string>(aec=> "Request ID="+requestID.Get(aec).ToString())
},
replyLeaveRequestID
},
};
service = new WorkflowService
{
Name = "AddService",
Body = workflow
};
return service;
}
}
Right now, it is self hosted as highlighted below
namespace DemoWF
{
class Program
{
static void Main(string[] args)
{
LeaveRequest();
}
private static void LeaveRequest()
{
_25_LeaveRequest receiveAndReplyWorkflow = new _25_LeaveRequest();
WorkflowService wfService = receiveAndReplyWorkflow.GetInstance();
Uri address = new Uri("http://localhost:8000/WFServices");
WorkflowServiceHost host = new WorkflowServiceHost(wfService, address);
try
{
Console.WriteLine("Opening Service...");
host.Open();
Console.WriteLine("WF service is listening on " + address.ToString() + ", press any key to close");
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("some thing bad happened" + e.StackTrace);
}
finally
{
host.Close();
}
}
}
}
The quickest way would be to create a WCF Workflow Service Application.
You'll get a workflow designer where you can drag and drop the activities you need:
And if you run the project in Visual Studio, you'll get an auto-generated WSDL with your service operation(s):
And also it will bring up Visual Studio's WCF Test Client tool:
You can create a workflow-based service that handles multiple methods by using the Pick Branch activity. Each branch would then have a Receive and Send Reply activity, with the receive activity moved to the trigger section and the send reply activity in the action part.
Each trigger would be for a specific operation on the service. In the following example, I define two operations: MyFirstOperation and MySecondOperation.
Below is what the WCF test client tool will show with multiple operations exposed from the workflow:
Hopefully that gets you started. The topic of standing up workflow-based WCF services can get quite involved. :)

HTTP self-hosting and unit tests

I am working on a set of unit tests, which include testing of HTTP client/server functionality, with a self hosted server. But I can't get even the simplest test to work. HEre is my code
UnitTest1.cs
using System;
using System.Net.Http;
using System.Web.Http.SelfHost;
using NUnit.Framework;
using SomeWebService;
namespace UnitTestProject1
{
[TestFixture]
public class UnitTest1
{
[Test]
public void TestMethod1()
{
var baseAddress = new Uri("http://localhost:9876");
var config = new HttpSelfHostConfiguration(baseAddress);
new Bootstrap().Configure(config);
var server = new HttpSelfHostServer(config);
using (var client = new HttpClient(server))
{
client.BaseAddress = baseAddress;
var response = client.GetAsync("").Result;
Assert.True(response.IsSuccessStatusCode, "Actual status code: " + response.StatusCode);
}
}
}
}
Bootstrap.cs
using System.Web.Http;
namespace SomeWebService
{
public class Bootstrap
{
public void Configure(HttpConfiguration config)
{
config.Routes.MapHttpRoute(name: "API Default", routeTemplate: "{controller}/{id}", defaults: new
{
controller = "Home",
id = RouteParameter.Optional
});
}
}
}
and the HomeController.cs
using System.Net.Http;
using System.Web.Http;
namespace SomeWebService
{
class HomeController:ApiController
{
public HttpResponseMessage Get()
{
return this.Request.CreateResponse();
}
}
}
The test results in:
Actual status code: NotFound
Expected: True
But was: False
What am I doing wrong?
Packages installed
Install-Package Microsoft.Net.Http -version 2.0.20710
Install-Package Microsoft.AspNet.WebApi.SelfHost -version 4.0.20918
Install-Package Microsoft.AspNet.WebApi.Core -version 4.0.20710
If you want your tests to run even faster, you can avoid the whole TCP/IP stack by using a purely in-memory host,
[Test]
public void TestMethod1()
{
var config = new HttpConfiguration();
new Bootstrap().Configure(config);
var server = new HttpServer(config);
using (var client = new HttpClient(server))
{
client.BaseAddress = baseAddress;
var response = client.GetAsync("").Result;
Assert.True(response.IsSuccessStatusCode, "Actual status code: " + response.StatusCode);
}
}
HomeController is private, because you haven't explicitly declared it public. Try making it public:
public class HomeController:ApiController
{
public HttpResponseMessage Get()
{
return this.Request.CreateResponse();
}
}