Lets say I have a WCF service that a client can use to receive message from some server side message queue. As an example, lets say there is a server-side queue of email in a data table:
ID | MESSAGE_TEXT | SENT
------------------------
1 | Hi! | N
2 | A 2nd Msg | N
Lets define our service as:
[OperationContract]
public List<string> GetMessages()
{
var messages = LoadMessagesFromDb();
var messageText = (from m in messages select m.MessageText).ToArray();
return messageText;
}
Lets assume that LoadMessagesFromDb() just grabs all the messages where SENT = 'N'. So we load those, and then extract all the text strings and return them.
Now my issue here is that I really need to mark those messages as "sent = 'Y'" in my data table. I could do something like:
[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;
}
However, what happens if there is an error in returning the data to the client? Possibly a connectivity issue, or a WCF serialization issue? What I'd really like to do is somehow know that the client received the message successfully. The only thing I can think of right now is make a 2nd method that the client can call to indicate that the items were received successfully:
[DataContract]
public class Message
{
[DataMember]
public long ID { get; set; }
[DataMemeber]
public string Text { get; set; }
}
then have a 2nd method on the service:
[OperationContract]
public List<Message> GetMessages();
[OperationContract]
public void ConfirmMessagesReceived(List<long> messageIds);
So the client would have to send all the IDs back to me. Is there a better way to do this? If I were doing this in ASP.NET instead of WCF, I could have the method open the response stream and write back the data, and have that in a try/catch, but I don't seem to have the same flexibility in WCF, without making a bunch of custom message writers and extensions... Anyone have a better idea how to tell if there is an error during transmit back to the client? Does ws-reliablemessaging give me anything?
ReliableSessions (available with the WsHttpBinding) would transparently ensure that your messages are received by the client in the case of transport-level errors. Errors in the serialization layer on the client side would have to be handled there.
If you needed more acknowledgment from the client, you could implement a duplex service (using the WsDualHttpBinding) contract to easily communicate back to the server from the client.