Хостинг WCF сервиса на IIS 7 для Silverlight приложения
После переноса WCF сервиса с компьютера разработчика на сервер хостинг-провайдера возникает несколько проблем. В интернете вы найдёте противоречивые статьи и обсуждения на форумах, предлагающие то слишком избыточные решения, а то и вовсе ошибочные.
Поэтому я собрал в одном месте минимально достаточные инструкции по настройке WCF сервиса. Исходные возможности такие: хостинг с IIS7, ASP.NET 2.0, .NET Framework 3.5 SP1 (хостинг-провайдер masterhost, конфигурация Windows 2008 хостинга на текущее время), WCF сервис для Silverlight2 приложения. Отсутствует возможность запуска в командной строке сервера любых утилит для настроек IIS под WCF а также запуска IIS Manager Administration Tool (masterhost предоставляет возможность использовать для IIS7 Manager Administration Tool, но эта утилита не будет работать если ваш доступ в интернет осуществляется через proxy-сервер). Необходимо добиться устойчивой работы WCF сервиса.
Шаг 1. Single WCF Service in multiple domains
Деплоим Web проект на сервер хостинга и проверяем работу WCF сервиса: http://domain.tld/MyService.svc
Появляется сообщение об ошибке «Server Error in ‘/’ Application.» и предложение установить в файле конфигурации Web.config тэг <customErrors mode=»Off»> для возможности узнать детальные сведения об ошибке. Устанавливаем требуемые настройки, не забывая, что позднее их необходимо будет вернуть в прежнее состояние для production сервера.
<configuration>
<system.web>
<customErrors mode="Off"/>
</system.web>
</configuration>
Снова тестируем сервис: http://domain.tld/MyService.svc
Теперь мы видим сообщение об ошибке, оно гласит:
[ServiceActivationException: The service ‘/WcfService.svc’ cannot be activated due to an exception during compilation. The exception message is: This collection already contains an address with scheme http. There can be at most one address per scheme in this collection. Parameter name: item.]
Многие источники рекомендуют в данной ситуации написать свой ServiceHostFactory, но этого делать не надо! Для исправления этой ошибки достаточно добавить в файл конфигурации тэг baseAddressPrefixFilters с указанием протокола, хоста и порта сервера на котором размещается ваш сервис. Например, если ваш сервис располагается по адресу http://domain.tld:8080/Services/WcfService.svc, то порт необходимо указать, а вот путь /Services/WcfService.svc — нет, т.е. мы используем строку «http://domain.tld:8080/».
Было:
<configuration>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
</configuration>
Стало:
<configuration>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
<baseAddressPrefixFilters>
<add prefix="http://domain.tld"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
</configuration>
Полностью секция system.serviceModel должна выглядеть так:
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="Namespace.WcfServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
<baseAddressPrefixFilters>
<add prefix="http://domain.tld"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
<services>
<service behaviorConfiguration="Namespace.WcfServiceBehavior" name="Namespace.WcfService">
<endpoint address="" binding="basicHttpBinding" contract="Namespace.WcfService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
</configuration>
Тестируем: http://domain.tld/MyService.svc, сервис работает.
Отлично, однако, это только начало.
Учтите, что локально WCF сервис при этом перестанет работать, а указать несколько префиксов с разными доменами, но одинаковым протоколом невозможно, поэтому ввиду большого числа различий между файлами конфигурации Web.config на хостинге и на компьютере разработчика, рекомендуется редактировать их раздельно и отключить deploy этого файла на production сервер.
На компьютере разработчика соответственно префикс должен быть таким:
<add prefix="http://localhost:1656/"/>
или с другим портом в соответствии с вашими настройками. Либо лучше вообще закомментировать в файле конфигурации разработчика всю секцию baseAddressPrefixFilters, т.к. порт может меняться, и его правка причинит неудобства.
Кстати при разработке WCF сервисов для удобства разработчика желательно настроить использование постоянного порта для сервера встроенного в среду разработки (Visual Studio Development Server).
Не забудте отредактировать на сервере хостинга файл Web.config, убрав тэг <customErrors mode=»Off»/>. Заодно для production сервера рекомендуется отключить режим отладки в тэге <compilation debug=»true»>.
Шаг 2.
Другая ошибка, с которой вы можете столкнуться: IIS не видит .svc файл, сообщая об ошибке 404 — файл не найден.
Один из советов заключается в том, что необходимо установить Windows Communication Foundation в Панели управления->Установка и удаление->Включение и отключение компонентов Windows. Но так как нам недоступны такие операции на сервере хостинга, то проблема решается редактированием в файле Web.config специфичной для IIS7 секции system.webServer. Мы добавляем в нее Handler для обработки *.svc файлов.
<configuration>
<system.webServer>
<handlers>
<remove name="SvcHandler"/>
<add name="SvcHandler" path="*.svc" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" resourceType="Unspecified" preCondition="integratedMode" />
</handlers>
</system.webServer>
</configuration>
Шаг 3.
Теперь нам необходимо настроить Silverlight приложение на работу с WCF сервисом расположенным не на компьютере разработчика, а на сервере хостинга.
Рассмотрим файл ServiceReferences.Config расположенный в корне Silverlight приложения:
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_WcfService" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:1656/WcfService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_WcfService" contract="WcfReference.WcfService" name="BasicHttpBinding_WcfService" />
</client>
</system.serviceModel>
</configuration>
Меняем адрес сервиса на реальный:
<endpoint address="http://domain.tld/WcfService.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_WcfService" contract="WcfReference.WcfService" name="BasicHttpBinding_WcfService" />
Шаг 4. Cross domain WCF access
Запускаем Silverlight приложение. При попытке обращения к WCF сервису оно выдает сообщение об ошибке:
An error occurred while trying to make a request to URI ‘http://domain.tld/WcfService.svc’. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. Please see the inner exception for more details.
Для устранения этой ошибки необходимо разместить в корне вашего Web-сервера (обратите внимание — в корне сервера, а не приложения) файл clientaccesspolicy.xml со следующим содержимым:
<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="SOAPAction">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
Далее
Индикатор загрузки (progress bar) для Silverlight
Индикатор загрузки для WPF рассмотренный ранее теперь доступен и для Silverlight. Изменения минимальны, убрано использование элементов, которые не поддерживает Silverlight, это Viewbox, и Timeline.DesiredFrameRateProperty.
Также вы можете увидеть как это работает прямо на этом сайте (требуется установленный Silverlight 3 Beta):
Вы видите 4 варианта индикатора:
- Исходный вариант, вращающийся индикатор
- Применен DiscreteDoubleKeyFrame для эффекта перелива
- Применен DiscreteDoubleKeyFrame с поправкой на число кружков, стали заметны ошибки расположения кружков по окружности
- Отлаженный вариант. Применен DiscreteDoubleKeyFrame и кружки расположены точно по окружности примением трансформации RotateTransform
Те, кто не может посмотреть пример в работе, может взглянуть на статичный скриншот, хотя в этом мало смысла — оценивать динамику по скриншоту 🙂
Загрузить компонент Circular Progress Bar и тестовый проект для Silverlight (13,4 Кб)
ДалееКак добавить Silverlight приложение на любой сайт?
Если вам захотелось разместить на своем сайте погодный информер про который я писал ранее в статье «Silverlight 2 погодный информер на основе сервиса Gismeteo.ru» , но движок вашего сайта не позволяет размещать Silverlight приложения, то вы можете просто вставить на любую страницу своего сайта следующий код:
<iframe src="http://iis.gis4all.org/service/gismeteo-informer-iframe.aspx" frameborder="0" width="270" height="200" scrolling="no" />
Все! Проверяем:
Разумеется для того, чтобы увидеть приложение, пользователю необходимо установить Silverlight на свой компьютер, однако эта установка настолько простая и быстрая, и на текущий момент уже 25% пользователей интернета её выполнили. Попробуйте и вы.
ДалееSilverlight 2 погодный информер на основе сервиса Gismeteo.ru
Изучать что-либо лучше всего на полезном но не сложном примере.
Для того, чтобы научиться работать в Silverlight с веб-сервисами, я выбрал создание погодного информера.
Для начала заходим на сайт http://gismeteo.ru/, переходим по ссылке «Погодный информер» и нажимаем кнопку «Получить код» в разделе «Данные в формате XML».
После выбора своего города мы получаем ссылку на XML сервис.
Запомним, что нам необходимо дать возможность пользователю переключить информер на другой город путем ввода соответствующего кода. Для получения кода своего города, пользователю придется зайти на страницу поиска.
Условием использования данного сервиса является размещение логотипа проекта Gismeteo.Ru или текстовой строчки «Предоставлено Gismeteo.Ru» с обязательной гиперссылкой на сайт. Загрузим с этой же страницы логотип в формате форматах Adobe Illustrator или CorelDRAW. К сожалению я не нашел простого способа конвертировать форматы AI, PS, CDR в XAML, поэтому пришлось установить дополнительный plugin XAMLExport для Adobe Illustrator, с помощью которого и экспортировался логотип Gismeteo. Перед экспортом, я уменьшил размер логотипа в 10 раз, при этом по всей видимостии выполняется некоторая генерализация, потому, что размер выходного XAML файла тоже уменьшился.
Сохраняем себе также описание формата данных:
TOWN информация о пункте прогнозирования:
index уникальный пятизначный код города
sname закодированное название города
latitude широта в целых градусах
longitude долгота в целых градусах
FORECAST информация о сроке прогнозирования:
day, month, year дата, на которую составлен прогноз в данном блоке
hour местное время, на которое составлен прогноз
tod время суток, для которого составлен прогноз: 0 — ночь 1 — утро, 2 — день, 3 — вечер
weekday день недели, 1 — воскресенье, 2 — понедельник, и т.д.
predict заблаговременность прогноза в часах
PHENOMENA атмосферные явления:
cloudiness облачность по градациям: 0 — ясно, 1- малооблачно, 2 — облачно, 3 — пасмурно
precipitation тип осадков: 4 — дождь, 5 — ливень, 6,7 — снег, 8 — гроза, 9 — нет данных, 10 — без осадков
rpower интенсивность осадков, если они есть. 0 — возможен дождь/снег, 1 — дождь/снег
spower вероятность грозы, если прогнозируется: 0 — возможна гроза, 1 — гроза
PRESSURE атмосферное давление, в мм.рт.ст.
TEMPERATURE температура воздуха, в градусах Цельсия
WIND приземный ветер
min, max минимальное и максимальное значения средней скорости ветра, без порывов
direction направление ветра в румбах, 0 — северный, 1 — северо-восточный, и т.д.
RELWET относительная влажность воздуха, в %
HEAT комфорт — температура воздуха по ощущению одетого по сезону человека, выходящего на улицу
На этом мы прощаемся с сайтом GisMeteo и приступаем к разработке Silverlight погодного информера.
Заметим, что Gismeteo.Ru не предоставляет Web сервиса а просто возвращает XML файл в так называемом REST формате, поэтому для получения XML файла нам достаточно функциональности класса WebClient.
Теперь добавим еще несколько возможностей, которые придадут информеру полноценную функциональность. Во первых необходимо запоминать город, который ввел пользователь — это приятно, т.к. создает впечатление, что о вас помнят 🙂 Проще всего это сделать используя Cookies.
Далее
Свежие комментарии