Как отписаться от наблюдателя на стороне сервера

У меня есть приложение, которое использует RX через удаленное взаимодействие с одним сервером (наблюдаемым) и многими клиентами (наблюдателями). Моя проблема заключается в том, что когда клиент (наблюдатель) отключается неправильно, не выполняя подписку (удаление), функция OnNext() на сервере начинает выдавать исключение удаленного взаимодействия.

Есть ли какой-либо механизм для отмены подписки на проблемный наблюдатель на стороне сервера?

Часть клиентского кода:

internal void SetRemoting(bool refreshInstance)
{
    string channelName = "RemotingClientUI";
    IDictionary dict = new Hashtable();
    dict["port"] = 9988;
    dict["name"] = channelName;

    var bcp = new BinaryClientFormatterSinkProvider();
    var channel = new TcpClientChannel(dict, bcp);
    ChannelServices.RegisterChannel(channel, false);

    _remoteServer = (IRemoteServerService) Activator.
        GetObject(typeof (IRemoteServerService),
            tcp://...");
}

private void SubscribeToRemoteEvents(bool unSubscrubeFirst)
{            
    _jobRowUpdate = _remoteServer.JobRowUpdate.Subscribe(UpdateJobQueueRow);
    _packageRowUpdate = _remoteServer.PackageRowUpdate.   
        Subscribe(UpdatePackageQueueRow);
    _miscUpdate = _remoteServer.MiscAction.Subscribe(MiscRemoteActions);
}

Часть кода сервера:

public class RemoteServiceService
{
    public RemoteServiceService()
    {
        JobRowUpdate = LoggerFactory.GetLogger(
            LoggerType.RemoteService, this).JobRowUpdate.Remotable();
        PackageRowUpdate = LoggerFactory.GetLogger(
            LoggerType.RemoteService, this).PackageRowUpdate.Remotable();
        MiscAction = LoggerFactory.GetLogger(
            LoggerType.RemoteService, this).MiscActions.Remotable();
    }
}

public class RemoteLoggerForService
{
    private RemoteLoggerForService(IService service)
    {
        _jobRowUpdate = new Subject<IJobQueueRow>();
        _packageRowUpdate = new Subject<IPackageQueueRow>();
        _miscActions = new Subject<MiscRemoteObjects>();
        _service = service;
    }

    #region Overrides of LoggerBase

    public override void WriteToLog<T>(T stringFormatOrObject, 
        params object[] args)
    {
        lock (this)
        try
        {
            lock (LockLogger)
            {
                if (stringFormatOrObject is IJobQueueRow && 
                    _jobRowUpdate != null)
                {
                    _jobRowUpdate.OnNext(
                        stringFormatOrObject as IJobQueueRow);
                }

                if (stringFormatOrObject is IPackageQueueRow && 
                    _packageRowUpdate != null)
                {
                    _packageRowUpdate.OnNext(
                        stringFormatOrObject as IPackageQueueRow);
                }

                if (stringFormatOrObject is MiscRemoteObjects && 
                    _miscActions != null)
                {
                    _miscActions.OnNext(
                        stringFormatOrObject as MiscRemoteObjects);
                }
            }
        }
        catch(Exception ex)
        {
            LoggerFactory.GetLogger(LoggerType.File, null).
                WriteToLog(
                    Utils.GetFullException("RemoteLoggerForService", ex));
        }
    }

    #endregion
}

person user1960639    schedule 09.01.2013    source источник
comment
Попробуйте перефразировать это. Я не понимаю вашего вопроса. Похоже, вы можете смешивать проблемы с Rx и удаленным взаимодействием, когда проблема связана с одним или другим.   -  person Dave Hillier    schedule 09.01.2013
comment
Наблюдаемый объект и наблюдатели находятся на разных компьютерах. Я использую расширение ISubject‹T›.Remotable(). Все работает нормально, но отключение клиента приводит к краху сервера с исключением удаленного взаимодействия. Вопрос в том, как заставить коллекцию Observable игнорировать или удалить подписку клиента, который уже отключился   -  person user1960639    schedule 09.01.2013
comment
Как вы подписываетесь? Вы добавили обработчик ошибок/исключений? или улов? Вам нужно предоставить больше информации.   -  person Dave Hillier    schedule 09.01.2013
comment
я обновил вопрос   -  person user1960639    schedule 09.01.2013
comment
Вы можете рассмотреть другой подход... например, PushQa, который использует Rx + SignalR и OData и IQbservables для удаленных подписок. petegoo.github.com/Pushqa   -  person DoctorFoo    schedule 10.01.2013


Ответы (1)


Я думаю, что вы пытаетесь проглотить исключение и продолжить работу своего сервера. Вы можете сделать это, перехватив исключение (как вы сделали здесь), которое вы затем можете передать методу OnError соответствующего Observable, чтобы подписчики могли затем выбрать, как реагировать.

person Jim Jeffries    schedule 05.01.2015