ArticleDirectory
- Define a callback contract
- Implement an operation in a callback contract
- Call an operation in the callback contract
- Callback operations and threads
- Binding and two-way channel
So far, the exercises and examples you have seen in this book are concentrated on the C/S model. In this model, a server provides a service that waits for the client to send a request, receives the request from the client, processes the request, and then selectively sends the request to the client. Program Send a response. The client program is a participant in the activity. It submits requests and effectively determines when the service starts to execute. However, this is only the case in most cases. WCF also supports other processing systems, such as point-to-point network and client callback. In point-to-point scenarios, there is no passive service. All participants are independent clients because they can communicate equally. At this time, there is no client/server relationship, so the participant should be prepared to process the messages sent to it at any time. Using the client callback, the service can call a method in the client program. In fact, the client and server in the C/S management are converted. During the callback, the original server and client will be called and the server will become the client, the client becomes the server. In this chapter, you will investigate how to define the client callback and how to use the client callback to implement a simple event mechanism, which is used to notify clients that the status of the services that follow the service status has changed. Implement and call a client callback in the traditional C/S protocol. When the Host Program opens the servicehost object, the service listens for messages on one or more endpoints established by the WCF Service Architecture. However, the client program may expect to only receive response messages, and the response message is sent to the client by the client through implicit requests. Once the client opens a channel with the service, the service will be activated during the WCF runtime to send additional messages (for communication) to the client ), when the client sends a statement that has received an additional message, the Service stops sending this additional message. WCF provides two features to implement this function: callback contract and two-way channel. When using callback, it is very important that the callback can only be used when the client sends a request to the service; the callback must also be called in the channel initialized by the client and used to send requests. Define a callback contract. A callback contract defines the operations that the service can perform in the client. A callback contract is very similar to a service contract because they are both an interface or a class, and the operations it contains are marked with the operationcontract feature. In terms of semantics, interfaces and classes are different. The difference is whether to use the servciecontract feature. The following example defines a method that the service can call to notify the client of a change in the product price. The client that listens for callback implements each method in the callback contract. There are two necessary conditions for the callback of the service identification client: the Service implements the callback operation defined in the service contract, and the client must reference the service contract (the service contract that implements the callback contract ). To achieve this, you can use the callbackcontract attribute in the servicecontract feature class to mark the service contract, as shown in the following Code As shown in:
The purpose of this Code is that the client calls the changeprice operation to update the price of a specific product. After the price of the product is modified, the service calls the onpricechanged operation on the client, then return a modified product to the service. You should note that other operations in the iproductsservicev3 service contract can also call the onpricechanged operation, because the callback contract is bound with the service contract, rather than the song operation in the service contract. Implement an operation in a callback contract. When you try to build a client proxy to access a service associated with the callback contract in the service contract, the proxy class must be based on the system. servicemodel. duplexclientbase class. The structure of the proxy class is roughly as follows: the content in the yellow box shows the difference with that of the common proxy, because the common proxy does not need to define the callback contract. The developer should create a client program that should contain a class which implements the iproductsservicev3callback interface and the onpricechanged method of the interface. The productsservicev3client proxy class extends the duplexclientbase <iproductsservicev3> class, and it also contains many constructors that client programs can use to instantiate proxy objects. The appeal code snippet only shows two constructors. The main features of all constructors are that the first parameter is an instancecontext object. This is a key feature that allows a service to call the client. You should be clear about the meaning of the "instance context" specified for the service through instacnecontextmode. It does not matter if it is unclear. Let's recall that each instance of the service runs in its own context and stores the instance status information. Each instance of the service has its own context. When a service instance is instantiated, these contexts are created and automatically initialized at the WCF runtime. When will these contexts be initialized? Three situations of initialization context are listed below:
- the client starts a new session (if the service specifies the context mode of the persession instance)
- the client calls an operation of the service (if the service specifies the context mode of the percall instance)
- the Host Program of the service starts the Service (if the service specifies the single instance context mode)
When a client connects to a service instance, information about a specific service instance is stored in the communication channel for message transmission between the client and the service, therefore, a message can be guided to the correct service instance during the WCF operation. When implementing a client callback, you must provide the same functions so that the server can route messages back to the correct client when running the WCF Service. To achieve this goal, you need to create an instancecontext object pointing to a specific client program instance. When you connect to the service through a proxy, the instacecontext object is passed to the service, the client automatically includes the client instance information in the request message during the client's WCF operation, and then sends the request message to the service. If the service needs to call the operations in the callback contract, the service directly calls the appropriate client instance through the context object. The following code shows how to implement the iproductsservicev3callback interface in the client proxy: The this parameter in the constructor of instancecontext points to the object that implements the iproductsservciev3callback contract. The statement used to create a proxy object in the dosomework method references the instancecontext object. If the service calls the onpricechanged operation through the instancecontext object, the server's WCF runtime will call the onpricechanged method in the client instance. Note that the callbackclient class also implements the idisposable interface. The dispose method is used to disable the proxy. Once the client connects to the service and sends an initialization message, the Service may call back the client instance at any time. If the client program closes the proxy immediately after sending a request to the Service in the dosomework method, the service fails to call back the client instance because the client instance object is no longer valid. As shown in the code above, if the client instance continues to exist after the dosomwwork method, disable the proxy object in the dispose method to ensure that the service can call back the client instance at any time, unless the client program is terminated or the client object is explicitly destroyed. To call an operation in the callback contract, the Service must obtain a reference from the client instance sending a request to the service. As you can see, the server uses the service's operation context to obtain the client instance information when running the WCF Service. You can access the operation context through the stunned operationcontext. Current attribute, which returns an operationcontext object. The operationcontext class provides the getcallbackchannel method of generic. This method can return a channel reference. This channel is the channel for communication between the service and the client that calls the service. The Return Value of the getcallbackchannel method refers to the reference of the contract type. You can call this reference operation. As shown in the following code: it is very likely that after the client calls the service operation and the service is calling back the client, especially when the client calls the service operation in one way, the client starts to terminate or close the communication channel. Therefore, you should check whether the channel callback channel has been closed before the service executes the callback, as shown in the code in the yellow square below: All WCF channels implement the icommunicationobject interface. This interface provides the state attribute. You can use this attribute to determine whether the channel is still open. If the value of the state attribute is not communicationstate. openned, the service should not try to use the callback. If the service calls an operation in the callback contract, the client code may also implement the callback contract so that other operations can be called back in the service. By default, the server uses a single thread to process callback execution during the WCF runtime. Therefore, the callback to the Service may cause the service to block the thread that processes the initialization request. In this case, the WCF runtime detects the current situation and then throws an invalidoperationexception, the exception message is "this operation wocould deadlock because the reply cannot be encoded ed until the current message completes processing ". To avoid this situation, you can set the concurrency mode in the callback implementation class of the client program: Start multithreading (if the client program code is thread-safe ), or start re-import (if the client program code is not thread-safe, but the data used by the client is consistent before multiple calls ). To achieve this, you need to apply the callbackbehavior feature to the callback implementation class in the client program, and set the concurrencymode attribute value of this feature class to concurrenymode. muitiple or concurrencymode. reentrant.
Not all Bindings for binding and bidirectional channels support client callback. To support client callback, you must bind a client that supports two-way communication. The connection end must be able to initialize communication, and the other end must be able to accept communication. The TCP transmission protocol and the namedpipes protocol are two-way. Therefore, you can use nettcpbinding to bind netnamepipebinding when implementing client callback. The model implemented by the HTTP protocol does not support bidirectional operations. Therefore, you cannot use basichttpbinding binding, wshttpbinding binding, or ws2007httpbinding binding. This seems to have a major flaw in the HTTP-based Intranet system. However, for this reason, WCF provides wsdualhttpbinding binding to address this defect. This binding creates two HTTP channels (one for sending requests to the client and the other for sending requests to the client). Of course, this binding hides the implementation details, therefore, it is not only necessary to treat it as a normal two-way binding. There are some important differences between wsdualhttpbinding binding and wshttpbinding binding and ws2007httpbinding binding. In particular, wsdualhttpbinding binding does not support transmission-level security, but it still implements reliable sessions (and you cannot disable this feature)