WCF WebService - есть ли способ определить, что клиент получил ответ?

Допустим, у меня есть служба 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 ответ

Решение

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

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

Другие вопросы по тегам