Хостинг WebAPI с использованием OWIN в службе Windows
У меня есть собственный веб-API с использованием OWIN (внутри службы Windows). Насколько я понимаю, этого достаточно, чтобы HTTP-запросы приходили на службу Windows. Я могу удалять URL WebAPI (http://localhost/users
) локально (с той же машины), но не с других машин. Я использую порт 80, IIS остановлен. Другие веб-сайты (размещенные в IIS, на порту 80) работают нормально, когда IIS работает.
//В службе windows:
public partial class Service1 : ServiceBase
{
...
...
protected override void OnStart(string[] args)
{
Console.WriteLine("Starting service...");
string baseAddress = "http://localhost:80/";
WebApp.Start<Startup>(baseAddress); //This is OWIN stuff.
}
...
...
}
public class Startup
{
// This code configures Web API. The Startup class is specified as a type
// parameter in the WebApp.Start method.
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
var config = new HttpConfiguration();
WebApiConfig.Register(config);
appBuilder.UseWebApi(config);
}
}
Нужно ли мне что-то делать, чтобы заставить эту работу работать с другими машинами?
(Я чувствую, что входящие HTTP-запросы не пересылаются службе Windows, а только в IIS. Когда вы нажмете локально, возможно, он не проходит через модуль ОС, который слушает HTTP-запросы. Просто предположите.)
Ответы
Ответ 1
Брандмауэр вашего компьютера может блокировать входящие запросы. Вы можете сделать:
Вы можете запустить команду wf.msc
, чтобы открыть брандмауэр Windows в режиме повышенной безопасности и добавить новое правило входящих в порт TCP 80.
(Вы должны заметить пару входящих правил, начиная с World Wide Web Services...
. Это для IIS. Я не уверен, что разрешить эти правила будет достаточно, чтобы даже ваша служба Windows могла получать запросы... вы можете попробовать и посмотрите, работает ли это иначе, как было предложено ранее, вы можете создать новое правило для входящих событий.)
Обновление:
Основываясь на вашем комментарии, возможно, из-за регистрации вашего Url вы не можете попасть в службу. Ниже приведены некоторые примеры регистрации нескольких URL-адресов с помощью HttpListener.
StartOptions options = new StartOptions();
options.Urls.Add("http://localhost:9095");
options.Urls.Add("http://127.0.0.1:9095");
options.Urls.Add(string.Format("http://{0}:9095", Environment.MachineName));
using (WebApp.Start<Program>(options))
{
Подробнее о регистрации URL вы можете узнать по следующим ссылкам:
http://technet.microsoft.com/en-us/library/bb630429.aspx
http://technet.microsoft.com/en-us/library/bb677364.aspx
Ответ 2
Есть две вещи, которые не позволят вам использовать что-либо, отличное от "localhost" в службе Owin:
- Приложение должно запускаться как admin, чтобы открыть порт с другим именем хоста, как "localhost". Вы можете исправить это, либо запустив приложение с правами администратора, либо добавив исключение для данного порта, используя:
netsh http add urlacl url=http://*:9000/ user=<your user>
- Брандмауэр Windows может блокировать трафик с других компьютеров. В моем случае брандмауэр не блокировал локальный трафик (я мог добраться до
http://localhost:9000
или http://127.0.0.1:9000
или http://192.168.1.193:9000
), который был моим локальным IP-адресом с того же компьютера, но ему необходимо было добавить исключение порта в брандмауэр, чтобы разрешить получение этой службы с другого компьютера).
Ответ 3
Я столкнулся с подобной проблемой. Ниже решение работало для меня.
StartOptions options = new StartOptions();
options.Urls.Add("http://localhost:9095");
options.Urls.Add("http://127.0.0.1:9095");
options.Urls.Add(string.Format("http://{0}:9095", Environment.MachineName));
using (WebApp.Start<Program>(options))
{
...
}
Ответ 4
На самом деле это простой надзор, который я также споткнулся: если вы только слушаете запросы на localhost, 127.0.0.1 и т.д. - никто никогда его не увидит, потому что только вы (я) понимаете вас в качестве этой цели. На моей машине я localhost, если я req ваш IP на любом порту, эта служба увидит get http://your_ip:80, а не localhost. Все, что вам нужно сделать, это выполнить на "http://*: {0}", и таким образом вы можете onStart() передать порт.