Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WCF, Web Services, Remoting Новый топик    Ответить
 Какие средства в wcf можно использовать...  [new]
sanekoffice
Member

Откуда:
Сообщений: 366
для реализации такой простой идеи:

Есть несколько клиентов и сервер.
1) Клиент передает сообщение серверу
2) Сервер рассылает это сообщение "подписчикам"

Сервер представил как InstanceContextMode.Single, автохост для управления через форму.

Первый этап я реализовал оч просто (банальный tcp-биндинг). Сообщения принимаю. Теперь нужно средство "вещания" или типо того, чтобы сервер отправил данные всем клиентам из списка. Сам список, вероятно, формируется так: при запуске клиента он отправляет запрос на сервер "запиши меня в список и если что, отошли сообщение". Все компьютеры внутри локальной сети.

Но а саму отправку от сервака клиенту как реализовать?
7 июл 17, 11:16    [20622139]     Ответить | Цитировать Сообщить модератору
 Re: Какие средства в wcf можно использовать...  [new]
МихаилР
Member

Откуда: Ижевск
Сообщений: 252
sanekoffice,

Ну если говорить конкретно о WCF, то самый очевидный вариант использовать callback или, иначе, duplex services

Другое дело, что
  • это работает не для всех протоколов это работает. Если будете использовать стандартные биндинги, то проверьте по таблице поддерживается ли Duplex режим.
  • довольно много требуется всякого инфраструктурного кода, например, обработки ошибок, что какой-то клиент "отвалился".
  • этот механизм специально не ориентировали на массовую рассылку, поэтому многие вещи (например, асинхронную рассылку) нужно делать самому.
  • его достаточно сложно отлаживать (по сравнению с прямым запросом WCF)

    Поэтому, если нет специальной привязки именно к WCF, я бы поискал другие варианты. Например
  • SignalR
  • Очередь сообщений, с поддержкой нескольких подписчиков Service Bus for Windows Server, RabbitMQ, ...
  • 8 июл 17, 10:57    [20625441]     Ответить | Цитировать Сообщить модератору
     Re: Какие средства в wcf можно использовать...  [new]
    sanekoffice
    Member

    Откуда:
    Сообщений: 366
    МихаилР,
    Немного не понял каким образом мне вызывать callback на стороне всех клиентов.
    В данном виде он отправляет ответ тому клиенту, от которого пришел запрос. Как же мне отправить остальным?

       
        [ServiceContract(CallbackContract = typeof(IDuplexMessagesCallback))]
        public interface IDuplexMessage
        {
            [OperationContract]
            void GetMessageFromClient(EntityBaseWcf item);
        }
        public interface IDuplexMessageCallback
        {
            [OperationContract(IsOneWay=true)]
            void SendMessageToClient(EntityBaseWcf item);
        }
    
        // реализация на стороне сервера
        public void GetMessageFromClient(EntityBaseWcf item)
        {
             SetLog(item.Name);
             OperationContext.Current.GetCallbackChannel<IDuplexMessagesCallback>().SendMessageToClient(item);
        }
    


    P.S. на счет альтернатив спасибо, почитаю. Но мне любопытно реализовать именно в wcf. Хочу как следует ознакомиться с ее возможностями
    10 июл 17, 09:05    [20627915]     Ответить | Цитировать Сообщить модератору
     Re: Какие средства в wcf можно использовать...  [new]
    МихаилР
    Member

    Откуда: Ижевск
    Сообщений: 252
    sanekoffice
    МихаилР,
    Немного не понял каким образом мне вызывать callback на стороне всех клиентов.


    Если очень приближенно, то схема выглядит так:
    1. У вас есть Callback контракт, с помощью которого, вы будете отсылать уведомления на клиентов
    +
    [ServiceContract]
    interface INotificationContract
    {
        [OperationContract(IsOneWay = true)]
        void SendNotification(Notification notification);
    }
    
    [DataContract]
    public class Notification
    {
        /* Some properties */
    }
    


    2. Для того, чтобы клиенты могли подписываться/отписываться от нотификаций вы делаете специальный сервис. Вот его контракт:
    +
    [ServiceContract(CallbackContract = typeof(INotificationContract))]
    interface INotificationService
    {
        [OperationContract]
        void Subscribe();
    
        [OperationContract]
        void Unsubscribe();
    }
    


    3. Внутри этого сервиса вы просто ведете учет всех подписавшихся и отписавшихся клиентов:
    +
    class NotificationService : INotificationService
    {
        internal static ISet<INotificationContract> callbacks = 
            new HashSet<INotificationContract>();
    
        public void Subscribe()
        {
            INotificationContract callback = 
                OperationContext.Current.GetCallbackChannel<INotificationContract>();
    
            callbacks.Add(callback);
        }
    
        public void Unsubscribe()
        {
            INotificationContract callback =
                OperationContext.Current.GetCallbackChannel<INotificationContract>();
    
            callbacks.Remove(callback);
        }
    }
    


    4. Теперь, когда у вас есть список клиентов, которые желают получить уведомления, вы можете каждому из них отправить сообщение:
    +
    var notification = new Notification();
    
    NotificationService.callbacks.ToList().ForEach(cl => cl.SendNotification(notification));
    


    Как-то так.
    Понятно, что это ни разу не продакшен код. Как минимум здесь нужно:
    - Это не многопоточное решение (я про список callbacks) - нужно заменить на нормальный вариант
    - Для избавления от дубликатов callbacks здесь используется простой хэш-код класса. На сколько я помню, это не очень хороший вариант (какой хороший, правда тоже не помню - по-моему, обычно советуют присылать с клиенте некий уникальный код клиента)
    - Рассылка уведомлений идет в один поток и не асинхронными методами (т.е. последний в списке получит уведомление не пойми когда, а если там еще будут ошибки, ...)
    - Нет обработки ошибок отсылки (например, клиент отпал) - как результат, если в середине списка что-то упадет, то хвост списка свое уведомление не получит вообще никогда

    Но сама идея вроде понятна.
    10 июл 17, 11:02    [20628326]     Ответить | Цитировать Сообщить модератору
     Re: Какие средства в wcf можно использовать...  [new]
    sanekoffice
    Member

    Откуда:
    Сообщений: 366
    МихаилР,
    Спасибо! Очень доходчиво объяснили.
    10 июл 17, 11:06    [20628344]     Ответить | Цитировать Сообщить модератору
    Все форумы / WCF, Web Services, Remoting Ответить