WCF WebService - есть ли способ определить, что клиент получил ответ? - PullRequest
3 голосов
/ 21 декабря 2009

Допустим, у меня есть служба WCF, которую клиент может использовать для получения сообщения из некоторой очереди сообщений на стороне сервера. Например, предположим, что в таблице данных есть очередь электронной почты на стороне сервера:

ID | MESSAGE_TEXT | SENT
------------------------
1  | Hi!          | N
2  | A 2nd Msg    | N

Давайте определим наш сервис как:

[OperationContract]
public List<string> GetMessages()
{
    var messages = LoadMessagesFromDb();
    var messageText = (from m in messages select m.MessageText).ToArray();
    return messageText;
}

Предположим, что LoadMessagesFromDb () просто захватывает все сообщения, где SENT = 'N'. Поэтому мы загружаем их, а затем извлекаем все текстовые строки и возвращаем их.

Теперь моя проблема заключается в том, что мне действительно нужно пометить эти сообщения как "sent = 'Y'" в моей таблице данных. Я мог бы сделать что-то вроде:

[OperationContract]
public List<string> GetMessages()
{
    var messages = LoadMessagesFromDb();
    var messageText = (from m in messages select m.MessageText).ToArray();

    // mark sent
    foreach(var msg in messages)
        MarkSentInDb(msg.ID);

    return messageText;
}

Однако что произойдет, если при возврате данных клиенту возникнет ошибка? Возможно, проблема с подключением или проблема с сериализацией WCF? То, что я действительно хотел бы сделать, так или иначе знать, что клиент получил сообщение успешно. Единственное, о чем я могу думать сейчас, - это создать 2-й метод, который клиент может вызвать, чтобы указать, что элементы были получены успешно:

[DataContract]
public class Message
{
    [DataMember]
    public long ID { get; set; }

    [DataMemeber]
    public string Text { get; set; }
}

тогда есть 2-й метод на службе:

[OperationContract]
public List<Message> GetMessages();

[OperationContract]
public void ConfirmMessagesReceived(List<long> messageIds);

Так что клиент должен будет отправить все идентификаторы обратно мне. Есть лучший способ сделать это? Если бы я делал это в ASP.NET вместо WCF, у меня мог бы быть метод, открывающий поток ответов и записывающий данные, и делающий это в try / catch, но у меня нет такой гибкости в WCF , не делая кучу пользовательских писателей сообщений и расширений ... Кто-нибудь есть лучшая идея, как определить, есть ли ошибка при передаче обратно клиенту? Ws-reliablemessaging дает мне что-нибудь?

1 Ответ

3 голосов
/ 21 декабря 2009

ReliableSessions (доступно с WsHttpBinding) будет прозрачно гарантировать, что ваши сообщения будут получены клиентом в случае ошибок транспортного уровня. Ошибки на уровне сериализации на стороне клиента должны быть обработаны там.

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

...