views:

89

answers:

1

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?

+2  A: 

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.

Ray Vernagus
Thanks Ray. I am using wsHttpBinding already, so I think the Reliable Sessions will work for me. I just need to see how non-wcf clients like it. Some of our clients use Java, and I think one is on VB5 still.
rally25rs