应用程序
我正在做一个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控制台服务器获取报告。
您可以通过使用方法创建新的控制器来扩展您的服务