Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add wcfcore perf testing and deploy service with corewcf #4884

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the Sdk ""Microsoft.NET.Sdk.Web" and remove the package reference to Microsoft.AspNetCore

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If change to "Microsoft.NET.Sdk.Web", visualstudio will throw IndexOutOfRangeException exception

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CoreWCF.Http" Version="1.1.0" />
<PackageReference Include="CoreWCF.NetTcp" Version="1.1.0" />
ZhaodongTian marked this conversation as resolved.
Show resolved Hide resolved
<PackageReference Include="CoreWCF.Primitives" Version="1.1.0" />
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using CoreWCF;
using System.Threading.Tasks;

namespace WCFCorePerfService
{
[ServiceContract]
public interface ISayHello
{
[OperationContract]
Task<string> HelloAsync(string name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using CoreWCF.IdentityModel.Selectors;
using System;
using System.Threading.Tasks;

namespace WCFCorePerfService
{
public class MyCustomValidator : UserNamePasswordValidator
{
public override ValueTask ValidateAsync(string userName, string password)
{
if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password))
{
return new ValueTask(Task.CompletedTask);
}
ZhaodongTian marked this conversation as resolved.
Show resolved Hide resolved
return new ValueTask(Task.FromException(new Exception("username and password cannot be empty")));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using CoreWCF;
using CoreWCF.Configuration;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Diagnostics;
using System.IO;
using System.Net;

namespace WCFCorePerfService
{
public class Program
{
static void Main(string[] args)
{
string filePath = Path.Combine(Environment.CurrentDirectory, "WCFCorePerfService.exe");
Console.WriteLine(filePath);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a better option is Assembly.GetEntryAssembly().Location as the exe doesn't need to be launched from the current directory.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assembly.GetEntryAssembly().Location will return the full path of coreWCFPerfService.dll. but I need to get the full path of exe and add into firewall

string command = $" advfirewall firewall add rule name=\"WCFCorePerfService\" dir=in protocol=any action=allow program=\"{filePath}\" enable=yes";
ExecuteCommand(command, Environment.CurrentDirectory, TimeSpan.FromSeconds(20));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better option is to directly modify the firewall. You can find some old code which does this here. It's basically a helper class which uses the COM component for programming the firewall and includes automatic cleanup of process exit. I believe this will work now as there's COM support in recent versions of .NET.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have use COM to add rules in the firewall. but this only support in windows OS

Console.WriteLine("Application start.");

using (var host = CreateWebHostBuilder(args).Build())
{
host.Start();

Console.WriteLine("Service is Ready");
Console.WriteLine("Press Any Key to Terminate...");
Console.ReadLine();
}

command = $" advfirewall firewall delete rule name=\"WCFCorePerfService\" program=\"{filePath}\"";
ExecuteCommand(command, Environment.CurrentDirectory, TimeSpan.FromSeconds(20));
Console.WriteLine("Clean up the firewall rule.");
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseKestrel(options =>
{
options.ListenLocalhost(8080);
options.Listen(IPAddress.Loopback, 8443, listenOptions =>
{
listenOptions.UseHttps();
}
);
})
.UseNetTcp(8808)
.UseStartup<Startup>();

public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddServiceModelServices();
}

public void Configure(IApplicationBuilder app)
{
WSHttpBinding serverBinding = new WSHttpBinding(SecurityMode.TransportWithMessageCredential);
serverBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
app.UseServiceModel(builder =>
{
builder.AddService<SayHello>();
builder.AddServiceEndpoint<SayHello, ISayHello>(new BasicHttpBinding(), "/WCFCorePerf/TestService.svc/BasicHttp");
builder.AddServiceEndpoint<SayHello, ISayHello>(new NetTcpBinding(SecurityMode.None), "/WCFCorePerf/TestService.svc/NetTcp");
builder.AddServiceEndpoint<SayHello, ISayHello>(serverBinding, "/WCFCorePerf/TestService.svc/WSHttp");
Action<ServiceHostBase> serviceHost = host => ChangeHostBehavior(host);
builder.ConfigureServiceHostBase<SayHello>(serviceHost);
});
}

public void ChangeHostBehavior(ServiceHostBase host)
{
var srvCredentials = new CoreWCF.Description.ServiceCredentials();
srvCredentials.UserNameAuthentication.UserNamePasswordValidationMode
= CoreWCF.Security.UserNamePasswordValidationMode.Custom;
srvCredentials.UserNameAuthentication.CustomUserNamePasswordValidator
= new MyCustomValidator();
host.Description.Behaviors.Add(srvCredentials);
}
}

private static int ExecuteCommand(string command, string workingDirectory, TimeSpan timeout)
{
Process process = new Process();
process.StartInfo.FileName = "netsh";
process.StartInfo.Arguments = command;

if (workingDirectory != null)
{
process.StartInfo.WorkingDirectory = workingDirectory;
}

process.StartInfo.UseShellExecute = false;
process.Start();

bool flag;
if (timeout.TotalMilliseconds >= Int32.MaxValue)
{
flag = process.WaitForExit(Int32.MaxValue);
}
else
{
flag = process.WaitForExit((int)timeout.TotalMilliseconds);
}

if (!flag)
{
process.Kill();
}

if (!flag)
{
throw new TimeoutException(string.Format("Command '{0}' was killed by timeout {1}.", new object[]
{
command,
timeout.ToString()
}));
}

return process.ExitCode;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System;
using System.Diagnostics;
using System.Threading.Tasks;

namespace WCFCorePerfService
{
public class SayHello : ISayHello
{
public Task<string> HelloAsync(string name)
{
return Task.Factory.StartNew(() => { return name; });
}
ZhaodongTian marked this conversation as resolved.
Show resolved Hide resolved

public bool Cleanup(string name)
{
string command = $" advfirewall firewall delete rule name=\"{name}\"";
bool flag = false;
int code = ExecuteCommand(command, Environment.CurrentDirectory, TimeSpan.FromSeconds(20));
if (code == 0)
flag = true;

return flag;
}

private int ExecuteCommand(string command, string workingDirectory, TimeSpan timeout)
{
Process process = new Process();
process.StartInfo.FileName = "netsh";
process.StartInfo.Arguments = command;
if (workingDirectory != null)
{
process.StartInfo.WorkingDirectory = workingDirectory;
}
process.StartInfo.UseShellExecute = false;
process.Start();
bool flag;
if (timeout.TotalMilliseconds >= Int32.MaxValue)
{
flag = process.WaitForExit(Int32.MaxValue);
}
else
{
flag = process.WaitForExit((int)timeout.TotalMilliseconds);
}
if (!flag)
{
process.Kill();
}

if (!flag)
{
throw new TimeoutException(string.Format("Command '{0}' was killed by timeout {1}.", new object[]
{
command,
timeout.ToString()
}));
}
return process.ExitCode;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32714.290
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoreWCFPerfService", "CoreWCFPerfService\CoreWCFPerfService.csproj", "{35B05C6A-9FF0-4A9C-9BBE-E88963416022}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WCFCorePerfClient", "WCFCorePerfClient\WCFCorePerfClient.csproj", "{D9001454-F77C-4053-B4AE-34342351FD49}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{35B05C6A-9FF0-4A9C-9BBE-E88963416022}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{35B05C6A-9FF0-4A9C-9BBE-E88963416022}.Debug|Any CPU.Build.0 = Debug|Any CPU
{35B05C6A-9FF0-4A9C-9BBE-E88963416022}.Release|Any CPU.ActiveCfg = Release|Any CPU
{35B05C6A-9FF0-4A9C-9BBE-E88963416022}.Release|Any CPU.Build.0 = Release|Any CPU
{D9001454-F77C-4053-B4AE-34342351FD49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D9001454-F77C-4053-B4AE-34342351FD49}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D9001454-F77C-4053-B4AE-34342351FD49}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D9001454-F77C-4053-B4AE-34342351FD49}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BD5D3AEC-A9AB-412C-A41B-A410030B454A}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.ServiceModel;
using System.Threading.Tasks;

namespace WCFCorePerfClient
{
[ServiceContract]
public interface ISayHello
{
[OperationContract]
Task<string> HelloAsync(string name);
}
}
Loading