Здравствуйте, Klatu, Вы писали:
A>>Много чего можно. Может расскажешь для чего тебе нужно, а тебе ответят подходит ли WCF?
K>Да я просто интересуюсь, чтобы быть в курсе. K>В чем основные отличия от Remoting, если не считать абстракцию над протоколами?
Если в двух словах, то WCF — это очередная библиотека для межпроцессного взаимодействия, которая является логическим развитием предыдущих подобных технологий мелкомягковский, в частности .Net Remoting и DCOM. Существенным отличием от двух предыдущих технологий является то, что WCF — это прежде всего технология для построения сервис-ориентированной архитектуры приложений (SOA — Service-Oriented Architecture), что позволяет абстрагироваться от конкретной технологии реализации и взаимодействовать с другими приложениями, написанными на любой другой платформе, языке, технологии (главное, чтобы эта реализация отвечала определенным правилам).
Если вы знакомы с ремоутингом, то отличия основные следующие: по-умолчанию, WCF не показывает наружу (not expose) никакие платформенно-зависимые детали реализации сервиса, такие как типы аргументов методов сервиса. Вместо этого, сервис представляет собой группу операций, которые получают некоторые абстрактные входные/выходные параметры. В частности, это позволяет написать сервис на WCF, а использовать его из Java. При этом существует такое понятие, как эквивалентность типов параметров, когда два типа считаются эквивалентными, если они имеют одно и тоже представление на уровне канала передачи данных, то их можно спокойно использовать взаимозаменяемым образом. Таким образом, можно ослабить зависимость между клиентом и сервисом и полностью устранить зависимость на уровне сборок: сервис публикует информацию о себе с помощью специального mex-интерфейса (так называемый Metadata Exchange Endpoint), и любой другой клиент (написанный на .net или любой другой технологии) может к нему подключиться и сгенерировать прокси-классы для взаимодействия с этим сервисом. Таким образом получается, что два типа являются эквивалентными, если они имеют одно и тоже представление на уровне канала передачи данных, что позволяет их посылать со стороны клиента и получать на стороне сервиса (и наоборот).
Кроме того, в DCOM и в ремоутинге было такое понятие, как прозрачность метоположение (location transparancy), т.е. мы на самом деле не знаем, является ли полученный нами объект реальным объектом, или же он является проксей к удаленному объекту (на самом деле узнать это можно вызвав RemotingServices.IsTransparentProxy но дело не в этом). В девяностых (и начале двухтысячных), многим казалось хорошей идеей, что мы можем работать с некоторым объектом и не задумываться над тем, является ли он локальным или удаленным, но практика показала, что пользовательский код должен четко знать, что он работает с удаленным объектом, поскольку это упрощает разделение коммуникационных ошибок от ошибок бизнес-логики, генерируемых удаленным объектом. Так что в WCF теперь есть четкое разделение и понимание того, что вы работаете с прокси, и вы можете спокойно отделить коммуникационные ошибки (Communication exceptions), от ошибок, произошедших в сервисе/клиенте. Все некоммуникационные ошибки также являются частью протокола взаимодействия между клиентом и сервисом (ведь мы можем работать с платформой у которых исключений может не быть вообще), поэтому они четко специфицируются в виде Faul Contract-ов, так что теперь, каждый метод сервиса должен четко говорить, что он может упасть и с чем.
Если вдаваться еще в какие-то частности различий в WCF и .Net Remoting, то процесс обратных вызовов (callbacks) в них реализован соверешнно по разному. Так, в WCF интерфейс обратного вызова также является частью контракта и задается непосредственно в контракте сервиса, это дает возможность в каждом вызове сервиса получить этот интерфейс, в случае необходимости сохранить его и потом вызвать метод этого интерфейса. Это поддерживается не всеми коммуникационными протоколами (посколько некоторые протоколы являются по своей сути однонаправленными) и тогда, в случае несовместимости, вы получите ошибку в процессе создания экземпляра сервиса.
Кроме этого, есть и очень важные отличия при использовании протокола Tcp, при работе с двусторонними каналами связи. Вообще, в ремоутинге с надежной двусторонней связью была полная беда, даже в букварях было написано, что реализовать надежную связь на ремоутинге через TCP было практически невозможно: ремоутинг втихую пытается восстановить соединение от клиента к серверу, а связь от сервера к клиенту автоматом не восстанавливалась (поскольку восстанавление происходило втихаря в момент вызова метода) и, самое главное, для обратной связи в ремоутинге требуется еще одно tcp-шное соединение, что делает невозможным нахождение клиента за NAT-ом.
adontz упоминал, что в WCF мы не можем воспользоваться MarshalByRef; формально — это действительно так, но на практике вы можете достаточно легко перейти с ремоутинга (использования MarshalByRef), на WCF сменив в WCF сериализатор по умолчанию с NetDataContractSerializer-а на NetDataContractSerializer-ом. Этот сериализатор, в отличие от сериализатора по умолчанию, добавляет в выходной сериализованный поток информацию о CLR-ном типе, что устраняет сервис-ориентированную кросс-платформенность, но позволяет использовать любые сериализируемые классы в виде аргументов (если классы аргументов использовались в ремоутинге и были помечены атрибутом Serializable, то их можно будет использовать и в WCF при использовании в нем NetDataContractSerializer-а).
В остальном, WCF является таким же "слоеным пирогом", как и ремоутинг, только количество этих слоев и их названия немного другие. Так что, если вам не хватает функциональности из коробки, то это дело можно расширить.
Если очень коротко, то вся инфраструктура состоит из двух главных слоев: 1. Service Model Layer и 2. Channel Layer. Каждый из этих слоев содержит еще кучу подуровней и вы можете вклиниться в каждый из них. Так, например, можно валидировать параметры обобщенным образом (например, всегда нужно, чтобы объекты определенного типа, которые используются в десятке методов сервиса обладали определенной характеристикой), самому создавать WCF сообщения, изменять существующие (добавив кастомное шифрование или что угодное еще), добавлять свои собственные каналы, которые, например, будут работать по UDP с вашей собственной кастомной системой по вашему собственному кастомному коммуникационному протоколу.
Так же, есть поддержка безопасности, транзакций; существует разные варианты инстанцирования экземпляров сервиса: на каждый вызов; на сессию; синглтон. Есть разные настройки по надежности доставки сообщений; можно настраивать таймауты, максимальные размеры сообщений и многое другое. Все это делается либо из кода, либо из конфигурационного файла.
В общем выводы такие:
Если на платформе .net вам понадобится межпроцессное взаимодействие, то первое на что стоит посмотреть — это WCF. Скорее всего, даже функциональности из коробки вам будет достаточно для реализации всех ваших потребностей, если же этого будет недостаточно, то вы всегда сможете расширить эту функциональность, по мере необходимости.