如何在一对多场景中使用IDuplexSessionRouter

本文关键字:IDuplexSessionRouter 一对多 | 更新日期: 2023-09-27 18:20:15

我的WCF服务是这样工作的:您可以通过调用服务方法来订阅它们,比如subscribe()。他们会在回调通道上向您发回结果,比如MessageReceived(字符串消息)。我现在的问题是,我的路由器只将第一个Subscribe调用路由到其端点列表中的第一个服务。因此,我只从一个服务端点得到回调消息,而不是同时从两个服务端点都得到。我希望订阅两个端点并从两个端点获得回调。这是我的代码(请注意,我在serviceAddresses字符串中有两个net.tcp地址):

private void StartAggregatorHost(List<string> serviceAddresses)
{
        // Create a new service host for the routing service (note that RoutingService is a pre-defined Microsoft service model type which routes SOAP messages).
        aggregatorHost = new ServiceHost(typeof(RoutingService));
        // Set up the router address. A logger client will now connect to this address to get logged messages.
        string fqdn = System.Net.Dns.GetHostEntry("localhost").HostName;
        string routerAddress = string.Format("net.tcp://{0}:2099/LogAggregator", fqdn);
        // Set up our router binding.
        NetTcpBinding routerBinding = new NetTcpBinding(SecurityMode.None, true);
        routerBinding.SendTimeout = new TimeSpan(0, 1, 0);       
        routerBinding.ReceiveTimeout = new TimeSpan(25, 0, 0);
        routerBinding.MaxReceivedMessageSize = int.MaxValue;
        routerBinding.MaxConnections = int.MaxValue;
        routerBinding.ListenBacklog = int.MaxValue;
        routerBinding.ReliableSession.Enabled = true;
        routerBinding.ReliableSession.Ordered = true;
        routerBinding.ReliableSession.InactivityTimeout = new TimeSpan(15, 0, 0, 0);
        // Define the type of router in use. For duplex sessions like in our case, we want to use the IDuplexSessionRouter.
        Type contractType = typeof(IDuplexSessionRouter);
        // Add the endpoint that the router will use to recieve and relay messages. Note the use of System.ServiceModel.Routing.IDuplexSessionRouter.
        aggregatorHost.AddServiceEndpoint(contractType, routerBinding, routerAddress);
        // Create the endpoint list that contains the service endpoints we want to route to.
        List<ServiceEndpoint> endpointList = new List<ServiceEndpoint>();
        foreach (string serverAddress in serviceAddresses)
        {
            // Set up our server binding(s) for each server.
            NetTcpBinding serverBinding = new NetTcpBinding(SecurityMode.None, true);
            serverBinding.SendTimeout = new TimeSpan(0, 1, 0);
            serverBinding.ReceiveTimeout = new TimeSpan(25, 0, 0);
            serverBinding.MaxReceivedMessageSize = int.MaxValue;
            serverBinding.MaxConnections = 1;
            serverBinding.ListenBacklog = int.MaxValue;
            serverBinding.ReliableSession.Enabled = true;
            serverBinding.ReliableSession.Ordered = true;
            serverBinding.ReliableSession.InactivityTimeout = new TimeSpan(15, 0, 0, 0);
            // Create the server endpoint the router will route messages to and from.
            ContractDescription contract = ContractDescription.GetContract(contractType);
            ServiceEndpoint server = new ServiceEndpoint(contract, serverBinding, new EndpointAddress(serverAddress));
            // Add the server to the list of endpoints.
            endpointList.Add(server);
        }
        // Create a new routing configuration object.
        RoutingConfiguration routingConfiguration = new RoutingConfiguration();
        // Add a MatchAll filter to the Router's filter table. Map it to the endpoint list defined earlier. When a message matches this filter, it will be sent to the endpoint contained in the list.
        routingConfiguration.FilterTable.Add(new MatchAllMessageFilter(), endpointList);
        // Attach the behavior to the service host.
        aggregatorHost.Description.Behaviors.Add(new RoutingBehavior(routingConfiguration));
        // Open the service host.
        aggregatorHost.Open();

        m_eventLog.WriteEntry(string.Format("Log aggregator service hosted at {0}.", routerAddress), EventLogEntryType.Information);
}

所以再一次。。。这就是我想要的:

CLIENT ---REQ---> ROUTER ---REQ---> SVC1
                         ---REQ---> SVC2
CLIENT <---CALLBACK1--- ROUTER <---CALLBACK1--- SVC1
       <---CALLBACK2---        <---CALLBACK2--- SVC2

这就是我现在得到的:

CLIENT ---REQ---> ROUTER ---REQ---> SVC1
CLIENT <---CALLBACK--- ROUTER <---CALLBACK--- SVC1

如何在一对多场景中使用IDuplexSessionRouter

我缺少的是优先级。我想传入列表会自动生成优先级,所以你需要单独添加每个服务并指定其优先级:routingConfiguration.FilterTable.add(new MatchAllMessageFilter(),new list{yourService},1);

相关文章:
  • 没有找到相关文章