Как я могу перезвонить клиенту и выставить новый канал с контекстом экземпляра - PullRequest
0 голосов
/ 15 сентября 2011

Я делаю WCF-сервис с netTcpBinding, который имеет главное лобби с несколькими чатами, в которые могут войти клиенты.Класс Lobby реализует ILobby в качестве контракта на обслуживание.

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

Например, на стороне службы у меня может быть

class Lobby : ILobby
{
    Dictionary<string, Chatroom> rooms;

    public void JoinRoom(string roomname)
    {
        if (rooms[roomname].TryEnter()) {}
    }
}

class ChatRoom : IChatRoom
{
    public bool TryEnter(string username)
    {
        ILobbyCallback callback =
            OperationContext.Current.GetCallbackChannel<ILobbyCallback>();
        // How do I do this next bit?
        callback.JoinedRoom(pass some instance context here);
        return true;
    }
}

На методе обратного вызова на стороне клиента я хочу

public void JoinedRoom(InstanceContext for the room on the service side)
{
    // Create a new WCF proxy using above InstanceContext
    // Create a WPF UI for the new room passing the proxy so it can communicate
    // with the room class directly without going via the root service
}

Возможно ли это?Какова лучшая практика для создания новых классов с их собственными контрактами на стороне обслуживания?Или мне просто нужно собрать все в один массивный класс MyService и обработать все самому?

1 Ответ

1 голос
/ 15 сентября 2011

Нельзя передать контекст экземпляра в качестве параметра для любого контракта на операцию. Это не имеет смысла, потому что этот контекст имеет локальную область видимости. Это называется «контекст экземпляра» = это контекст текущего экземпляра службы. В дуплексном сценарии и клиент, и сервер имеют собственную службу:

  • Клиенты вызывают сервис сервера через его прокси
  • Сервер вызывает службу клиента через полученный канал обратного вызова

Контекст экземпляра службы сервера имеет значение только на сервере. Непонятно, чего вы пытаетесь достичь (кроме очень сложной архитектуры).

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

Но действительно ли это нужно? Когда я смотрю на ваш код, я вижу, что одного сервиса и одного прокси достаточно. Также вашей операции JoinRoom вообще не нужно использовать обратный вызов, это может быть просто метод ответа на запрос.

...