Вопрос

Я создаю пользовательский интерфейс Silverlight 2 для удаленного инструмента.Есть два одновременных пользователя на разных сайтах, взаимодействующих с прибором (оператор за прибором и удаленный научный сотрудник), и любое количество пользователей-наблюдателей, которые не взаимодействуют с прибором, а просто наблюдают.Однако всякий раз, когда один из двух активных пользователей что-то меняет, эти изменения должны быть немедленно отражены в пользовательских интерфейсах всех пользователей, напримерпанорамирование или масштабирование изображения, аннотирование или выделение части изображения, добавление элементов в коллекцию, отображаемую в списке.В клиенте я использую наблюдаемые коллекции, которые легко отражают изменения, внесенные этим пользователем, но сложнее увидеть изменения, внесенные другим пользователем.Я могу опрашивать изменения от каждого клиента, но что-то вроде push-уведомлений было бы лучше.Я долго гуглил в поисках примеров, но не нашел ничего, что было бы именно тем, что мне нужно.Существуют всевозможные проблемы безопасности при взаимодействии Silverlight со службами WCF, которые означают, что многие потенциальные примеры просто не работают.У меня практически закончилось время на этот проект, и мне срочно нужна помощь.Есть ли у кого-нибудь какие-либо предложения по подходящему простому примеру, который иллюстрирует, как это сделать?Я опытный разработчик, но мне пришлось самостоятельно изучать сервисы Silverlight и WCF, и в моем регионе нет никого, кто что-либо знает об этом.Несмотря на то, что я проделал изрядный объем ASP.NET работы, я не веб-гуру / Javascript.Спасибо.

Это было полезно?

Решение

Push-уведомление поддерживается в Silverlight 2 с использованием новой поддержки WCF PollingDuplexHttpBinding. С Silverlight SDK установлено две сборки ( один для приложения Silverlight один для сервера WCF ).

У меня есть несколько блогов публикации и полный пример приложения , в котором показано, как «отправлять» обновления Stock с сервера консольных приложений, который самостоятельно размещает службу WCF для подключенных клиентов. В нем также показано, как каждый клиент может добавлять заметки к акции и синхронизировать эти заметки (отправленные с сервера) со всеми другими подключенными клиентами.

В последней версии примера (часть 4) показано, как синхронизировать push-обновления между клиентами Silverlight и WPF с использованием двух конечных точек сервера следующим образом:

using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace StockServer
{
    public class StockServiceHost : ServiceHost
    {
        public StockServiceHost(object singletonInstance, params Uri[] baseAddresses)
            : base(singletonInstance, baseAddresses)
        {
        }

        public StockServiceHost(Type serviceType, params Uri[] baseAddresses)
            : base(serviceType, baseAddresses)
        {
        }

        protected override void InitializeRuntime()
        {
            this.AddServiceEndpoint(
                typeof(IPolicyProvider),
                new WebHttpBinding(),
                new Uri("http://localhost:10201/")).Behaviors.Add(new WebHttpBehavior());

            this.AddServiceEndpoint(
                typeof(IStockService),
                new PollingDuplexHttpBinding(),
                new Uri("http://localhost:10201/SilverlightStockService"));

            this.AddServiceEndpoint(
                typeof(IStockService),
                new WSDualHttpBinding(WSDualHttpSecurityMode.None),
                new Uri("http://localhost:10201/WpfStockService"));

            base.InitializeRuntime();
        }
    }
}

Клиенты WPF подключаются к конечной точке WSDualHttpBinding, а клиенты Silverlight подключаются к конечной точке PollingDuplexHttpBinding той же службы WCF. В приложении также показано, как обрабатывать требования политики доступа клиента Silverlight.

Клиенты (Silverlight или WPF) могут добавлять заметки к акциям в своем пользовательском интерфейсе, и эти заметки распространяются обратно на сервер для отправки всем остальным клиентам. Это демонстрирует связь в любом направлении и, как мы надеемся, выполняет все необходимые коммуникации для вашего приложения.

Вы можете увидеть скриншот здесь работает демонстрационное приложение .

Другие советы

Не то, чтобы я толкаю Flex по-фанатски, но на самом деле это та архитектура, которую мы регулярно внедряем во все наши приложения на основе Flex. Вот что мы делаем на Flex - без сомнения, его можно было бы соответствующим образом перевести на Silverlight:

Для реализации этой возможности мы берем три компонента и объединяем их вместе.

<Ол>
  • Шаблон кометы (HTTP-совместимый способ отправки push-уведомлений на сервере - дополнительную информацию можно найти в Википедии)
  • разделы обмена сообщениями JMS (публикации / очереди подписчиков)
  • сервлет Adobe BlazeDS
  • Последний элемент реализует шаблон Comet, поддерживает маршалинг объектов AMF (двоичный формат сериализации Adobe для объектов ActionScript3) и соединяется с очередью или темой JMS. При соединении с темой несколько клиентов Flex, работающих в браузере, могут быть проксированы как подписчики на тему JMS. Поэтому, если какой-либо клиент публикует сообщение (или серверный код публикуется в теме), всем подписчикам клиента будет отправлено сообщение через BlazeDS и реализацию Comet Pattern.

    По сути, вам нужно найти или написать компонент, который выполняет то, что делает BlazeDS. Вам также может понадобиться реализовать некоторый клиентский код, который взаимодействует с шаблоном Comet этого серверного компонента.

    Поддерживает ли WCF шаблон Comet и двунаправленный обмен сообщениями? Особенно там, где соответствует HTTP и порт 80 или порт 443 для SSL. Похоже, вы уже изучили это и не нашли ничего для двунаправленного обмена сообщениями. Поэтому вам, возможно, придется закатать рукава и заняться кодированием.

    Обратите внимание на некоторые вещи, касающиеся отправки сервера в веб-приложение:

    BlazeDS поддерживает два основных режима реализации шаблона Comet (на самом деле есть третий вариант опроса, но я его игнорирую):

    <Ол>
  • давно опрос
  • потоковая передача HTTP
  • Долгосрочный опрос, который вы найдете более универсальным, поддерживается большинством веб-браузеров. Таким образом, вы могли бы упростить, чтобы просто поддержать это изначально. Или вы могли бы потратить время на то, чтобы ваш клиентский код сначала попробовал потоковую передачу по HTTP и переключился на длительный опрос, если это необходимо.

    Что касается брокера сообщений, который может обеспечить возможность публикации / подозрения, вы можете рассмотреть возможность использования ActiveMQ JMS. Это с открытым исходным кодом и бесплатно с активной поддержкой сообщества (вы также можете купить поддержку). Кроме того, вы можете использовать NMS для интеграции в качестве клиента .NET.

    Наличие посредника сообщений, находящегося на среднем уровне, на самом деле очень важно, потому что это место для безопасного размещения сообщений. Если ваши клиенты выполняют длинные опросы, вы не хотите, чтобы они пропускали какие-либо новые сообщения в течение интервала, когда они на самом деле не подключены.

    Еще одна вещь, которую необходимо учитывать в сценариях с большим объемом трафика (сотни или тысячи клиентов, например, веб-сайт в Интернете), необходимо использовать подход к масштабируемому шаблону кометы.

    В мире Flex / Java сервлет BlazeDS (с открытым исходным кодом) был модифицирован для работы с асинхронной моделью. В Java слушатель сокетов может быть построен для использования каналов NIO и потоковых потоков Java Concurrency Executor. Веб-сервер Tomcat имеет приемник NIO и поддержку асинхронных событий Servlet 3.0. В частности, BlazeDS был модифицирован для работы с веб-сервером Jetty. Суть в том, что масштабируемость этого асинхронного подхода означает, что отдельный физический веб-сервер может быть расширен для поддержки примерно до 20 000 одновременных клиентских подключений в стиле Comet.

    Прошло много времени с тех пор, как я серьезно занимался программированием на .NET, но привык к тому, что возможности io были во многом похожи на Java 1.1, за исключением возможности асинхронного обработчика результатов. Это, однако, не то же самое, что создание асинхронных слушателей сокетов через каналы Java NIO. Реализация канала NIO может поддерживать от сотен до тысяч соединений сокетов с относительно небольшим пулом потоков. Но C # и .NET прошли через

    Я просто хотел уточнить, что PollingDuplexHttpBinding не реализует «истинные» push-уведомления, поскольку раскрывает его имя (опрос). Из документации msdn :

      

    При настройке с этой привязкой клиент Silverlight периодически опрашивает службу на сетевом уровне и проверяет наличие любых новых сообщений, которые служба хочет отправить по каналу обратного вызова. Служба ставит в очередь все сообщения, отправленные по каналу обратного вызова клиента, и доставляет их клиенту, когда клиент опрашивает службу.

    Однако он более эффективен, чем традиционный способ опроса веб-службы, поскольку после каждого опроса сервер будет сохранять канал открытым в течение определенного времени (скажем, 1 минуты), и, если в это время приходит сообщение, оно будет непосредственно «отправить» сообщение клиенту. Клиент должен многократно возобновить соединение, так сказать, опрашивает сервис.

    Если вы хотите реализовать настоящие push-уведомления с помощью silverlight, я считаю, что вам нужно работать с сокетами, и я рекомендую прочитать некоторые сообщения в блоге Дэна Уолина на эту тему.

    В качестве альтернативы,

    если вам нужен собственный silverlight API без задействованных прокси, мостов или веб-серверов, вы можете использовать Nirvana из my-Channels в качестве промежуточного программного обеспечения для обмена сообщениями.Ознакомьтесь с Nirvana на my-Channels и на их сайте-витрине.(извините, я новый пользователь и не могу отправлять ссылки):

    Алекс

    РЕДАКТИРОВАТЬ: на самом деле работает нормально. Я был сильно укушен "скрытой переменной" в закрытии: (

    Я использовал PollingDuplex для SL2 и думаю, что он еще не готов к производству.

    Моя главная проблема заключается в том, что он не различает клиентов на одном компьютере. Если я запустлю 2 клиента, то один из них больше не сможет опрашивать сервер и умрет по истечении времени ожидания. Существует SessionId, который отличается для двух клиентов, но он просто игнорируется на стороне клиента.

    Аналогичным образом, если я убью клиента, а затем создам нового, новый клиент какое-то время получит push-обновления от предыдущего клиента.

    Кто-нибудь сталкивался с такими же проблемами или они исправлены в SL3?

    На самом деле, я запустил еще несколько демонстрационных кодов и понял, что по какой-то причине вам нужно указать InstanceContextMode и InstanceMode, чтобы служба основывалась на сеансах, а не на одиночном (насколько я могу судить). В простом демонстрационном коде, который я вытащил, есть явные проблемы с производительностью.

    К сожалению, такое поведение не было задокументировано.

    Моя организация обнаружила, что принудительная реализация Silverlight 2.0 / WCF немного "не готова к прайм-тайм", по крайней мере для того, для чего мы планировали ее использовать.

    В итоге мы выбрали XMPP / Jabber, потому что это более хорошо сформированный зверь, и вы можете довольно легко реализовать его в Silverlight, просто вытащив некоторые ресурсы из Интернета.

    Я верю, что Silverlight 3.0 будет реализовывать более новую / более правильно сформированную реализацию push, исходя из того, что я могу сказать из общедоступной информации.

    PollingDuplexHttpBinding, вероятно, самый элегантный способ сделать это.

    Еще одна менее сложная альтернатива - использовать TCP-сокет от клиента Silverlight. Когда одному из клиентов Silverlight необходимо отправить обновление, вы можете отправить ему TCP-сообщение, содержащее имя службы WCF, которую он должен вызвать, или некоторую другую легковесную информацию.

    Я использую этот подход для приложения, и он хорошо работает.

    Одно гораздо более простое и мощное решение на сайте http: //www.udaparts .com / документ / Учебное пособие / slpush.htm

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top