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 序列化问题?我真正想做的是以某种方式知道客户端已成功收到消息。我现在唯一能想到的是创建第二个方法,客户端可以调用该方法来指示已成功接收项目:
[DataContract]
public class Message
{
[DataMember]
public long ID { get; set; }
[DataMemeber]
public string Text { get; set; }
}
然后在服务上使用第二个方法:
[OperationContract]
public List<Message> GetMessages();
[OperationContract]
public void ConfirmMessagesReceived(List<long> messageIds);
因此客户端必须将所有 ID 发送回给我。有更好的方法吗?如果我在 ASP.NET 而不是 WCF 中执行此操作,我可以让该方法打开响应流并写回数据,并在 try/catch 中执行此操作,但我在 WCF 中似乎没有相同的灵活性,无需制作一堆自定义消息编写器和扩展...任何人都知道如何判断传输回客户端期间是否存在错误? ws-reliablemessaging 能给我什么吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
ReliableSessions(可与 WsHttpBinding 一起使用)将透明地确保您的消息在传输层错误的情况下由客户端接收。客户端序列化层中的错误必须在那里处理。
如果您需要客户端的更多确认,您可以实现双工服务(使用 WsDualHttpBinding) 合约可以轻松地从客户端与服务器进行通信。
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.