Using the routing service class to implement manual routing is undoubtedly a very powerful technology, but in common scenarios, all you want is to, based on some of the characteristics of the request, rather than writing some dynamic Algorithm To route messages. To deal with such a scenario, WCF provides the routingservice class, which is located in the system. servicemodel. Route namespace. Shows the class diagram in the namespace: routingservice class aims to implement Content-based routing when messages arrive. You can configure a routingservice object to check the information in the message header and route the message. You can also convert the content of the message body and then route the request based on the converted content. You can configure the routingservice class by using a filter table that contains one or more routing filters (the filter specifies the message matching conditions and the message push destination information after successful matching. A routing filter is actually an instance of the messagefilter class. You can dynamically create a messagefilter object and associate it with a routingservice object. However, most of the completion methods are to add filter information to the applications of the host routingservice object for each routing filter statically. Program And create the necessary messagefilter object according to the configuration file when running the service during the WCF runtime. We will also use this method in the following exercises. In the following exercise, you will change the routing policy of the shoppingcartservice. The server Load balancer algorithm is no longer used to send requests to shoppingcartservice instances listening on different ports. You route messages based on the request type: additemtocart messages and removeitemfromcart messages will be routed to an instance of shoppingcartservice, while getshoppingcart and checkout messages will be routed to another instance. Exercise: Host and configure the routingservice. 1. Use Visual Studio to open the shoppingcart. sln solution under the WCF \ step. By. Step \ solutions \ chapter14 \ shoppingcartservicewithrouter folder. This solution includes the continuous shoppingcartservice, shoppingcartservicehost, and shoppingcartguiclient projects, which are copied from chapter 7. Currently, the shoppingcartservice is configured with two HTTP endpoints that listen for requests at 9010 and 9020. They are bound using basichttpcontextbinding. 2. Add a new console application project to the shoppingcart solution. The project name in the console is staicrouter and saved in the WCF \ step. By. Step \ solutions \ chapter14 \ shoppingcartservicewithrouter folder. 3. reference the system. servicemodel, system. servicemodel. Routing component to the staticrouter project, and then reference the shopingcartservice project to the staticrouter project. 4. Open the programm. CS file of the staticrouter project; then add the following using statement in the file header 5. Add the following Code (Highlighted) to the main method of the programcs file: You should be familiar with the above code now. This Code creates an instance of the routingservice class and then mounts it to the servicehost object. You will define the configuration file for the service in subsequent steps. You will also specify the shoppingcartservice service address so that client requests can be routed to this address. 6. Add a configuration file for the staticrouter project and use the WCF Service Configuration Manager to open the configuration file. 7. On the configuration panel, right-click the service folder and click Create service. On the right panel, enter system. servicemodel. Routing. routingservice In the Name field. This is the complete name of the routingservice class. 8. On the configuration panel, select create service, right-click the endpoint under its folder, and select create service endpoint. On the service endpoint panel, set the attribute values according to the following table.
attribute |
value |
address |
http: // localhost: 9000/shoppingcartservice. SVC |
bind |
basichttpcontextbinding |
contract |
system. servivemodel. Routing. irequestreplyrouter |
The contract defines the message transmission mode implemented by the routingservice object. The irequestreply interface processes basic request/reply bidirectional modes based on one channel. It pushes the client request message to the service and routes the service response message to the corresponding client. You can also use other contracts. For example, iduplexsessionrouter, which allows the routingservice object to route the server's callback messages to the client; or isimplexsessionrouter, which routes messages to the service implementing the session in one way; or isimplexrentramrouter, this interface supports services that do not provide sessions.
Note: In chapter 16th, We will detail how to create and use a two-way channel. The irequestreplyrouter interface is defined in the system. servicemodel. Routing namespace. Its content is as follows: The irequestreplyrouter interface allows the routingservice class to push request and response messages asynchronously. This interface also supports transactions. Note that the action and replyaction attributes are marked as *. 9. In the configuration panel, expand the Advanced folder and click the service behavior folder. On the service behavior panel, click the create service behavior configuration link. 10. In the right pane, clear the behavior name, click Add, and select Add a route behavior element. This element contains the attributes you can use to configure the behavior of the routingservice or to specify the name of a route table. 11. On the configuration panel, expand the Untitled behavior and click the route element. In the right-side pane, enter shoppingcartserviceroutingtable in the filtertablename field. Make sure that the value of the routeonheadersonly attribute is true and set the soapprocessingenabled attribute to false. In the subsequent steps, you will specify a message filter element for the shoppingcartserviceroutingtable filter table. The routeronheadersonly attribute indicates whether to define the rules for filtering the message header or the message content when the filter elements in the table pass through the messages of the routingservice. In this exercise, messages are filtered based on the request action information contained in the message header, so the routeronheadersonly attribute is set to true. When the routingservice receives a request message, the routing service routes the request to a target service based on different bindings, which may be different from the implementation of message transmission requirements. The soapprocessingenabled attribute specifies whether the routingservice is converting messages according to the binding requirements. If this attribute is set to false, the routing service directly pushes the message to the target service without making any changes to the message. Otherwise, the routingservice checks the message and converts the format of the message to the format required by the target service. In this exercise, the shoppingcartservice uses basichttpcontextbinding to bind the service to the client program and transmit the context information of the service instance id. Because you need to pass the context information without any interference through the routingservice, because this attribute is set to false. 12. In the configuration panel, expand the client folder, right-click the endpoint folder, and create a new client endpoint in the ADD. On the client endpoint panel, set the attribute values according to the following table:
attribute |
value |
name |
shoppingcartserviehttpendpoint1 |
address |
http: // localhost: 9010/shoppingcartservice. SVC |
bind |
basichttpbinding |
contract |
* |
The address matches the first endpoint address of the shoppingcartservice hosted by the shoppingcarthost program. The "*" character in the contract indicates that the Service receives any message instead of some specified service contract messages. Note that the binding attribute is set to basichttpbinding instead of basichttpcontextbinding. The client uses basichttpcontextbinding to bind to the routingservice, so that the message header contains context information such as the service instance id. If the routing service also uses context binding to connect to the shoppingcartservice, The routingservice processes the context information received from the shoppingcartservice and deletes the context information from the message header, therefore, the context information is not transmitted to the client program. After basichttpbindg is bound, the routingservice service is prevented from returning the Response Message from the shoppingcartservice to the client, querying the context information from the response message, and deleting the context information. In addition, as we mentioned in the previous step, setting the soapprecessingenabled attribute to false also prevents the routingservice from removing context information in the message sent by the client program, therefore, the routingservice directly pushes these messages only for shoppingcartservice -- no changes are made. 13. Add the second client endpoint according to the following table.
attribute |
value |
name |
shoppingcartserviehttpendpoint1 |
address |
http: // localhost: 9020/shoppingcartservice. SVC |
bind |
basichttpbinding |
contract |
* |
14. Save the configuration file and exit the WCF Service Configuration Manager. 15. Open the app. config file under the staticrouter project. You will see that the above endpoint has been added to the configuration file. The filter list in the <fliters> element defines the rules for routing messages. Each filter has a unique name and a filtertype. The filter type specifies the type of the filtered message created by the message filter object. The action type will create an actionmessengerfilter object during the WCF runtime. This object can filter requests based on the Action Element in the message header. The filterdata attribute specifies the value corresponding to the action. If an action matches the value of filterdata, the WCF runtime checks each object corresponding to the filter name in the <filtertable> fragment, and routes the message to the endpoint specified by the matching object. For example, if the routingservice receives a message, the action value in the header of the message is success. The endpointname attribute in the filter table references the endpoints defined in the <client> fragment. With WCF, you can filter messages based on other conditions. For example, you can specify endpointaddress to define an endpointaddressmessagefilter. If you want to perform Filtering Based on the message body content, you can use XPath to create an xpathmessagefilter object. At this time, the flterdata attribute is used to define the data path in the message and the value of this attribute corresponds to an XPATH expression.
For more information about other filter types, see http://msdn.microsoft.com/en-us/library/system.servicemodel.routing.configuration.filtertype.aspx ). 16. regenerate the project. Now you can test the routingservice Host Program and configuration. However, to demonstrate that a message is correctly routed to two shoppingcartservice endpoints, you will configure the shoppingcarthost program and add a service action that shows the action and address of each received and sent message. Exercise: test the routingservice 1. Reference The messageinspector component in the shoppingcarthost project. 2. Use the WCF Service Configuration Manager to open the app. config file of the shoppingcarthost project. On the configuration panel, expand the Advanced folder, expand the extension, and then click behavior element extension. 3. In the lower right pane, click Create behavior element extension. In the extension configuration element Editor, enter messageinspector In the Name text box to add a type field, and then click the ellipsis after the field. In the behavior extension type browser dialog box, select the chpater14 folder, click the messageinspector component and then click the OPEN button. In the action extension type dialog box, click messageinspector. shoppingcartbehaviroextensionelement, and then click the OPEN button. In the edit extension configuration element dialog box, click OK. 4. On the configuration panel, expand the service behavior in the Advanced folder and click durabelservicebehavior. On the right panel, click Add, and then add the messageinspector behavior element to durableservicebehavior behavior. 5. Save the configuration file and exit the WCF Service Configuration Manager. 6. In the solution browser window, right-click the shoppingcart solution and set the startup project of the solution. Add the staticrouter project to the startup project group. Click "OK". 7. Start the solution in non-adaptive mode. The shopping cart GUI client window appears, and colleagues will also see a shoppingcarthost console program and staticrouter console program. 8. Enter the SA-M198 in the product code section in the shopping cart GUI window, and then click the Add button. Add another product WH-H098 to the cart. Click the settlement button. The client program will get the same results as we did before. 9. Switch to the console window of the shoppingcarthost project. You will see the message displayed by the message detector. Confirm that all additemtocart requests are sent to the service listening on port 9010, while chekcout messages are sent to the service listening on port 9020. 10. Close the shopping cart GUI window, and press enter in the console window to close the service host window and staticrouter window. In this chapter, you have learned how to configure service discovery to separate service addresses from Service implementations. In addition, you have learned three common service discovery modes supported by WCF: ad hoc, declaration and hosting. You also carefully studied how to implement the routing WCF Service. You have learned how to determine how to process request messages during the running of the WCF Service. The channel distributor that receives the message queries its endpoint distributor objects one by one. An endpoint distributor discloses the addressfilter and contractfilter attributes. The channeldispatcher object uses these attributes to check whether the endpoint distributor can receive messages. The endpoint distributor selected by the channel distributor starts to process messages and calls the corresponding methods of the service. You can provide your own addressfilter and contractfilter objects, as well as implement the idispatchoperationselector interface, to implement a custom endpoint distributor to receive and process messages. In addition, you can also see how to define a universal WCF Service, which can be used as a router of other services. This routing Service implements a method, this method can receive any message and push the message to the service that can process the message. Finally, you know how to use and configure the routingservice class to route messages based on the information defined in the configuration file.