如何使System.Net.HttpListener长时间运行,或者有更好的方法吗



应用程序

我正在做一个IIoT项目。我需要能够在一台HMI运行在Win7上的设备上接收简单的消息(json有效载荷(。在某些情况下,我们使用第三方MQTT,但在这种情况下,我关注的是HTTP,特别是C#(.NET Framework 4.0(中的一个小型HTTP服务器。不需要前端,只需要一个带有单个端点的api。

方法

我找到了System.Net.HttpListener,并让它在控制台应用程序中做我想做的事情,以进行初始测试。问题是我使用的是GetContext方法,它阻塞了主线程。直觉上,这不是我想要的,但我不知道更合理的方法。我看到有一个内置的异步方法HttpListener.BeginGetContext,但这足以满足我的要求吗?最终希望使用TopShelf NuGet软件包将其打包为一项服务。

不是在寻找一个代码完整的解决方案,而是合适的概念方法。

您可以使用Microsoft.Owin包在控制台应用程序中托管http控制器

这个想法是,在这种情况下,您不需要安装IIS。如果需要,您可以将应用程序托管为windows服务(使用TopShelf(。

然而,您正在使ASP控制器工作,不应该再使用HttpListeners了。

有很多可用的操作指南,比如这里的

简而言之,你必须

添加Microsoft.AspNet.WebApi.OwinSelfHost

在类似的代码中配置Owin

public class SelfHostStart 
{
private readonly WebSettings config;
public SelfHostStart(WebSettings config)
{
this.config = config;
}
void Start<T>(string hostAddress, string message)
{
if (string.IsNullOrEmpty(hostAddress))
throw new ArgumentException("hostAddress", $"no value to start host {message}");
var oh = new OwinHost();
server = oh.Start<T>(hostAddress, message);
}

public void Start()
{
if (config?.Enabled == true)
{
Start<Startup>(config.HostAddress, "webServer");
}
}
}              
public class WebSettings 
{
public bool Enabled { get; set; }
public string HostAddress { get; set; }
}

然后你可以创建Startup.cs来配置http主机,如下所示:

public class Startup
{
public void Configuration(IAppBuilder appBuilder)
{
HttpConfiguration config = GetHttpConfig(appBuilder);
ConfigureWebApi(appBuilder, config);
DEBUG
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.LocalOnly;
if
appBuilder.UseCors(CorsOptions.AllowAll);
appBuilder.UseWebApi(config);
}
public HttpConfiguration GetHttpConfig(IAppBuilder appBuilder)
{
var config = new HttpConfiguration();
// you may override some default behavior here
//config.Services.Replace(typeof(IHttpControllerActivator), new UnityControllerActivator());
//config.Services.Add(typeof(System.Web.Http.ExceptionHandling.IExceptionLogger), new ExceptionLog(appBuilder.CreateLogger<ExceptionLog>()));
//config.Services.Replace(typeof(System.Web.Http.ExceptionHandling.IExceptionHandler), new CustomExceptionHandler()); // to make ExceptionHandler works 
//config.MessageHandlers.Add(new LoggingHandler(appBuilder.CreateLogger("rest")));
return config;
}
public void ConfigureWebApi(IAppBuilder app, HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.EnsureInitialized();
}
}

和控制器(具有可用于服务客户端的方法的类(:

[AllowAnonymous]
public class StatusController : ApiController
{
public StatusController()
{
}
[Route("status")]
public StatusDto Get()
{
var res = new StatusDto
{
DbVersion = "123",
LocalCurrency = "USD",
SwiftCode = "12345", // just sample
};
return res;
}
}
public class StatusDto
{
public string DbVersion { get; set; }
public string LocalCurrency { get; set; }
public string SwiftCode { get; set; }
}

并在控制台中启动http服务器

var config = new WebSettings() { HostAddress = "http://localhost:8080" };
var start = new SelfHostStart(config);
start.Start();

您应该为控制台提供使用netsh http add urlacl命令(如(侦听http url的权限

netsh http add urlacl url=http://+:8080/user=everyone

然后您可以浏览http://localhost:8080/status并且应该从http控制台服务器获取报告。

您可以通过使用方法创建新的控制器来扩展您的服务

相关内容

  • 没有找到相关文章

最新更新