Использование WCF на Localhost в Azure - PullRequest
8 голосов
/ 02 декабря 2011

В итоге
Как получить доступ к службе WCF на локальном хосте при размещении в IIS на Azure? Azure не привязывает localhost или 127.0.0.1 к моему веб-сайту.

Детали
У меня есть приложение ASP.Net, размещенное на Azure. Я добавил .svc и некоторые рабочие процессы, которые я хочу использовать через WCF. Для простоты мое веб-приложение просто вызывает службу на localhost, поэтому у меня есть такие конечные точки в web.config;

<client>
  <endpoint address="http://localhost:8080/Router.svc/Case" binding="basicHttpBinding" contract="NewOrbit.ExVerifier.Model.Workflow.Case.ICaseWorkflow" name="Case" />
  <endpoint address="http://localhost:8080/Workflow/Case/Case_default1.xamlx" binding="basicHttpBinding" contract="*" name="Case_default1" />
</client>

Это прекрасно работает на моей локальной машине. Проблема заключается в том, что когда я публикую это в Azure, веб-сайт в IIS не получает привязку к localhost, а привязки всегда соответствуют фактическому IP-адресу сервера. В конечном итоге это выглядит в applicationHost.config:

<bindings>
   <binding protocol="http" bindingInformation="10.61.90.44:80:" />
   <binding protocol="https" bindingInformation="10.61.90.44:443:" />
   <binding protocol="http" bindingInformation="10.61.90.44:8081:" />
</bindings>

Итак, как только мое веб-приложение пытается вызвать службу на localhost (или 127.0.0.1 в этом отношении), оно мгновенно завершается неудачей. Само собой разумеется, если я захожу на сервер и меняю привязку, то все в порядке.

Что мне действительно странно, так это то, что существует множество примеров, когда люди обращаются к службам WCF на локальном хосте в Azure, поэтому я не могу понять, почему это так. Я установил osFamily до 2, и для отладки я включил веб-публикацию и удаленный доступ к рабочему столу, которые, я думаю, теоретически могут испортить ситуацию.

На что я уже посмотрел

  • Я могу переписать адрес конечной точки в моем коде во время выполнения, чтобы заменить локальный хост действительным адресом или динамически создать конечную точку, как описано Роном в ответах. К сожалению, я использую службу маршрутизации WCF, поэтому я могу создавать версии рабочих процессов. Это означает, что мой код вызывает конечную точку маршрутизатора, а маршрутизатор WCF по очереди вызывает фактическую службу / рабочий процесс, используя конечную точку, указанную в web.config. У меня нет контроля над разрешением конечных точек служб маршрутизации без, я думаю, написания целого набора логики маршрутизации, которая просто кажется большой работой, когда все, что я хочу, это вызвать localhost:)
  • Переключение на использование именованных каналов; Увы, это вызывает некоторые странные проблемы с рабочими процессами, возможно, из-за дуплекса, и я нахожусь в крайнем сроке, так что у меня нет времени, чтобы разобраться с этим моментом.

Ответы [ 2 ]

4 голосов
/ 02 декабря 2011

Вы должны построить адрес конечной точки динамически.

Шаг 1: В вашем ServiceDefinition.csdef вам необходимо объявить конечную точку.

<ServiceDefinition name="MyFirstAzureWorkflow" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="WorkflowWeb" vmsize="ExtraSmall">
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="Endpoint1" endpointName="WorkflowService" />
        </Bindings>
      </Site>
    </Sites>
    <Endpoints>
      <InputEndpoint name="WorkflowService" protocol="http" port="80" />
    </Endpoints>
    <Imports>
      <Import moduleName="Diagnostics" />
    </Imports>
  </WebRole>
</ServiceDefinition>

Шаг 2: Когда вы хотите позвонить в службу

var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["WorkflowService"].IPEndpoint;
var uri = new Uri(string.Format(
    "http://{0}:{1}/MyService.xamlx",
    endpoint.Address,
    endpoint.Port));
var proxy = new ServiceClient(
    new BasicHttpBinding(),
    new EndpointAddress(uri));
1 голос
/ 02 декабря 2011

Хорошо, вот как я это решил. ИМХО это взломать но по крайней мере это работает.

По сути, мне нужно добавить привязку "*", чтобы я мог сделать это в Powershell. Общий рецепт здесь: http://blogs.msdn.com/b/tomholl/archive/2011/06/28/hosting-services-with-was-and-iis-on-windows-azure.aspx

Это касается добавления поддержки именованных каналов, но принцип тот же. Я только что изменил скрипт Powershell на:

import-module WebAdministration
# Set up a binding to 8080 for the services 
Get-WebSite "*Web*" | Foreach-Object { 
  $site = $_;
  $siteref = "IIS:/Sites/" + $site.Name;
  New-ItemProperty $siteref -name bindings -value @{protocol="http";bindingInformation="*:8080:"}
}

Теперь это позволяет мне использовать http://127.0.0.1:8080/service.svc для доступа к моему сервису.

Примечание: вам нужно следовать остальной части рецепта, чтобы установить повышенный контекст выполнения и изменить режим выполнения powershell, поэтому следуйте ему внимательно

...