gpt4 book ai didi

c# - 用于管理需要与其托管应用程序进行对话的WCF状态服务的回调方法的正确性

转载 作者:太空宇宙 更新时间:2023-11-03 14:18:13 25 4
gpt4 key购买 nike

我正在利用WCF服务编写一个复杂的分布式应用程序。

要求

我的要求如下:


许多工作站(PC)上运行着相同的软件(我需要开发的应用程序)。
每个站点都将向其他站点发送消息(每个站点都有一个邻居)。站点将路由消息以到达每个消息的最终目的地(这是P2P上下文,需要本地路由)。
当某个站传递消息时,该站必须确保该消息到达目的地(世界上某个地方的另一个站)。由于性能原因,我无法创建使用同步方法路由消息的服务(服务调用将持续太多时间,轮询从来都不是一个好主意)。因此,需要考虑反馈消息传递:消息到达目的地后,目的地会将I-Received-The-Message消息发送回发送者。
使用这种方法,我需要我的工作站来实现服务,以便路由反馈消息。基本上,每次传递消息时,任务表中都会填充一条记录,指示需要确认消息传递。如果没有对该消息的反馈消息到达发送方站,则发送方站将尝试再次发送原始消息。


我不能做的

我知道对于P2P场景,有一种提供良好的服务类型,但是由于某些原因我不能使用它(我不会因为这些原因而打扰您)。
请接受我上面列出的要求。

我的解决方案

我采用了以下解决方案:

两个服务合同定义了用于发送(路由)普通消息和答复/传递确认消息的调用:

/* Routing routines */
[ServiceContract]
public interface IMessageRouting {
/* When a client receives the message, in the MyMessage type
there are some fields that helps the current station to
decide which neighbour station the received packet will
be routed to */
[OperationContract(IsOneWay = true)]
void RouteMessage(MyMessage msg);
}

/* Delivery-Confirm messaging */
[ServiceContract]
public interface IDeliveryConfirmMessageRouting {
/* When the final destination (THE FINAL DESTINATION
ONLY, not an intermediate hop station) obtains a
message, it will route back to the sender a reply message */
[OperationContract(IsOneWay = true)]
void RouteDeliveryConfirmMessage(MyDeliveryConfirmMessage dcmsg);
}


以下是服务实现:

/* This service will be self-hosted by my application in order 
to provide routing functionality to other stations */
[ServiceBehaviour(InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Single)]
public class StationMessagingService : IMessageRouting {
/* Constructing the service */
public StationMessagingService() { ... }
// Implementation of serive operations
public void RouteMessage(MyMessage msg) {
...
}
}


以及交货确认服务...

/* This service will be self-hosted by my application in order 
to provide delivery confirm message routing functionality
to other stations */
[ServiceBehaviour(InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Single)]
public class StationDeliveryConfirmService : IDeliveryConfirmMessageRouting {
/* This service is particular, I will discuss the following lines
before the constructors in the next paragraph after first
typing all the code */
public delegate void DeliveryMessageReceivedEventHandler(
object sender, String DeliveryMessageReceivedEventArgs);
public event DeliveryMessageReceivedEventHandler DeliveryMessageReceived;
/* Constructing the service */
public StationDeliveryConfirmService() { ... }
// Implementation of serive operations
public void RouteDeliveryConfirmMessage(MyDeliveryConfirmMessage dcmsg) {
...
/* In the end fire the event only if I am the destination
of this message, otherwise I must route this message */
if (...) { /* Omitting condition for clarity */
this.DeliveryMessageReceived(this,
"A delivery confirm message has arrived with this info: " +
dcmsg.Info()); /* Info contains string info */
}
}
}


此时,我准备托管我的服务:

/* My program */
public class Program {
// Program's entry point
static void Main(string[] args) {
// Defining the delivery check table (I have a special type/class for this)
DeliveryCheckTable DCT = new DeliveryCheckTable(...);
// Creating services
StationMessagingService SMS = new StationMessagingService();
StationDeliveryConfirmService SDCS = new StationDeliveryConfirmService();
// Event handlers registration (expalinations in the next paragraph)
SDCS.DeliveryMessageReceived += Program.DeliveryMessageReceivedHandler;
// Hosting
Uri MyBaseAddress = new Uri("http://services.myapplication.com/Services/");
using (ServiceHost hostMessagingSvc = new ServiceHost(SMS, MyBaseAddress),
ServiceHost hostDeliveryConfirmSvc = new ServiceHost(SDCS,
MyBaseAddress)) {
// Info on endpoints in config file
// Running services
hostMessagingSvc.Open();
hostDeliveryConfirmSvc.Open();
// ...
// Application's other operations
// For clarity and simplicity, just consider that the code
// here is some kind of infinite loop with actions in it
// where the GUI can commununicate with the user, somewhere
// in the application's code, there is a List where all
// sent messages are inserted and, when a delivery
// confirm arrives, the corresponding item in the list is cleared.
// The list is rendered as a table by the GUI.
// ...
/*** Arriving here somehow when my application needs to be shut down. ***/
// Closing services
hostMessagingSvc.Close();
hostDeliveryConfirmSvc.Close();
}
}
/* Event handlers for the delivery confirm messages
service (please be patient, these lines of code
will be discussed in short) */
static void DeliveryMessageReceivedHandler(object sender,
string DeliveryMessageReceivedEventArgs) {
/* Here I will perform actions on the List
deleting the row containing the ID of the
message sent whose confirm has arrived */
}
} /* Program class */


一些说明

从代码(运行和正常工作的代码)可以看出,我设法使托管服务通过回调与托管应用程序通信。
因此,典型流程如下:


我的一个邻居调用了我的应用程序的 void RouteMessage(... msg)服务例程,以便向我发送消息。
在服务例程中,我将检查消息头并查找目标,如果目标不是我,则将其路由到我的另一个邻居(更接近目标),否则将使用该消息。
如果我使用了该消息,则必须发回确认。
我将呼叫我的 void RouteDeliveryConfirmMessage(... msg)服务例程的邻居,以使其路由该传递确认消息。
每个站点都路由消息,如果发现站点是目的地,它将使用该消息。但是,当消息是确认消息,而工作站是目的地时,该工作站将使用确认并触发 DeliveryMessageReceived事件,从而导致处理程序例程启动并删除相应的表条目(这样,发送方将获得确认知道不再需要重新发送该消息(因为已正确接收该消息)。


应用环境

如您所见,我没有提供有关我的应用程序的许多细节,只是为了理解代码所必需的...发生这种情况的主要原因是:


我不想打扰我的应用程序设计问题和目标。
关于为什么选择某些方法,还有很多要说的话,但是那将是非常特定于上下文的,并且我可能会在一个无关的主题上过分深入。
有人可能会问:“为什么要使站点路由消息而不是提供从发件人到目的地的直接消息传递?”,“路由的目的是什么?服务不能让您直接呼叫目标站点的服务端点吗? ”。好吧,我需要在一个网络中管理对等网络,对等网络对整个网络只有一点点了解。新的对等方加入现有的对等方,并且它们仅具有指向某些站点端点的链接。对等点不需要完全了解网络,它可以使用邻居。但是,将此视为我的要求的一部分。


问题

好的,该提问了。只是一个问题。
我在这里描述的是我设法开发的一种解决方案,以使服务与其托管应用程序进行通信。这是我没有找到正确模式的问题。所以我发现了这种编码方式...
好吗?
这是最佳做法吗?
这是不好的做法吗?
那应该是不好的做法吗,正确的做法/方式是什么?如何解决服务及其托管应用之间的通信问题?

谢谢

最佳答案

只是一个问题。我在这里描述的是我设法开发的一种解决方案,以使服务与其托管应用程序进行通信。


您在此处描述的是一种将消息从一个端点传递到网络上的另一个端点的方法,而无需深入了解计划如何配置和标识节点之间的客户端端点的特定细节,或者为什么不只是发送邮件。邮件直接发送给目标收件人。您从未尝试过讨论WCF服务实际上如何以线程安全的方式与GUI应用程序进行任何交互的非常复杂的问题。那将是您的服务与其托管应用程序进行通信。

尽管我对您的应用程序不完全了解,但我认为您实际上要完成的工作是“管道”,它已作为WCF的功能提供。我建议研究WCF发现:


  WCF Discovery
  
  Windows Communication Foundation(WCF)支持使用WS-Discovery协议以互操作方式在运行时发现服务。 WCF服务可以使用多播消息或发现代理服务器向网络声明其可用性。客户端应用程序可以搜索网络或发现代理服务器以查找符合一组条件的服务。本节中的主题提供了概述,并详细描述了此功能的编程模型。

关于c# - 用于管理需要与其托管应用程序进行对话的WCF状态服务的回调方法的正确性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6077105/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com