Welcome to Windows Communication Foundation (WCF)
Top Tasks :

WCF Team Bloggers

Browse by Tags

All Tags » Channel Dev Tou... » Indigo   (RSS)

  • Live from TechEd Day 2

    I gave a chalk talk on channel development in the afternoon yesterday. I did a huge experiment for the second-half of the talk, which was to write a custom channel from scratch for the audience. That's the kind of theater that you can pull off in a chalk talk but not a regular breakout session. I started with a completely empty Visual Studio environment, wrote a web service, explained why the web service call crashed due to a protocol issue, and then fixed the crash by writing a custom channel. We had 46 people in the audience at the start. The capacity of the chalk talk theaters is only 32 people, but we secured about a dozen extra chairs from the lounges and people stood along the back. Capacity was an issue for several of the chalk talks yesterday. I saw one chalk talk for BizTalk that had crammed almost 60 people into the room. If you're in the audience, it starts getting quite warm after a while. The breakout session rooms are quite spacious on the other hand so I haven't seen any problems there. The Orlando venue has a tremendous capacity and a generally good layout. The only other difficulty was that the standard equipment was a non-adjustable over-ear headset microphone. In addition to making you look like a cross between a call-center worker and a pop star, that type of mic is pretty uncomfortable to wear for an hour and picks up a lot of extra noise if you move around while talking. I tried a half-dozen ways of putting the headset on to fix the issues before the AV guy offered a standard lapel microphone. They had one sitting in the AV case in the room. I don't know why they didn't make the proper equipment available from the start. I promised at the end of the talk that I'd post some resources. Ed Pinto and Kenny Wolf are giving a talk "Architecture of Microsoft Windows Communication Foundation and Common Extensibility Points" on Thursday at 4:30 PM. Steve Maine is giving the buzzword titled talk "Microsoft Windows Communication Foundation Syndication, AJAX and REST Services in Web 2.0 with .NET Framework 3.5" on Friday at 1 PM. There are six samples that I particularly recommend for channel developers. Chunking channel HttpCookieSession channel UDP transport WSE transport UDP activation Config code generator Finally, here is the code that was written during the talk. The scenario was based on an HTTP problem I described back in August . using System; using System.Collections.Generic; using System.Text; using System.ServiceModel; using System.ServiceModel.Channels; Read More...
  • Optional Interfaces on Binding Elements

    In the past I've talked a lot about the absolute minimum you need to do to write a working channel. However, what about the people that want all of the optional bells and whistles that can go along with channel development? There are several interfaces that you can implement on the binding element or in your custom channel solution to add functionality. I'm not going to go over these interfaces in detail today, but I did want to at least catalog the interfaces that are available. The base class for a channel binding element is taken up by the fact that you have to subclass BindingElement or TransportBindingElement. Therefore, the optional functionality is generally provided through interfaces that you can add to the binding element or on separate objects. WS-Policy export. The IPolicyExportExtension interface lets you define an ExportPolicy method that overrides the policy construction process. Metadata export. The IWsdlExportExtension interface lets you define an ExportContract and an ExportEndpoint method that override the metadata construction process. WS-Policy import. The IPolicyImportExtension interface has the reverse method ImportPolicy to consume policy statements. Metadata import. The IWsdlImportExtension interface has the reverse methods ImportContract and ImportEndpoint to consume metadata. IWsdlImportExtension also has a method called BeforeImport. Metadata consumption is done using a multi-phase process, where all of the importers get to look at the metadata once before actually doing the work. Configuration import and export. Configuration on the binding element is added by subclassing BindingElementExtensionElement. This is a separate object that has to parallel all of the settable properties on the binding element. Binding configuration import and export. If you put your binding element into a standard binding, then you can provide configuration for that binding as well. You need two separate objects subclassing StandardBindingElement and StandardBindingCollectionElement. Next time: Messaging is not a Transaction Read More...
  • Writing Channel Manager Essentials

    Once you've obtained a channel manager from the binding element, you have the first object that is usable for network communication. Although the two kinds of channel managers, channel factories and channel listeners, share many of the same methods, the use of those methods tends to be quite a bit different. I'm going through just the client-side channel factory in the list, but I'll point out some bits of information that differ between channel factories and channel listeners. To get a minimally working channel factory for a custom channel, you need to think about what you're going to do in five particular methods. The holdover from binding elements to channel managers is GetProperty. The implementation of GetProperty should at a minimum return a response for every interface that you had support for on the binding element. The return value itself should be exactly the same as well, for the values that would have been returned at the moment you created the channel factory. Future changes to the binding element settings should never change the values returned by the channel factory. Open is a hook to let you perform some work prior to making the first service call. This is your chance to do any preconnection work, like looking up credentials, that you want to have costed during startup rather than taking time during a service call. When programming against a service with a client proxy, opening the proxy is an optional step. However, even if the user doesn't open the proxy, your channel factory and channel will get opened prior to the first call taking place. Close is the hook to let you clean up any state left behind that takes time to get rid of, such as open network connections. There is a different meaning for Close between channel factories and channel listeners. Closing a channel factory is supposed to similarly close all of the channels created from that factory. Closing a channel listener doesn't touch the existing channels. Therefore, you're going to have to structure your state differently between the channel factory and channel listener. For the channel listener, you are essentially forced to push more state into the channels so that they can survive the destruction of their channel listener. Abort is a similar idea to Close, but is a part of the ungraceful shutdown process. Rather than nicely cleaning up the state, you are expected to take care of the state problem by blowing it away with abandon. Abort should never do anything with the network or Read More...
  • Writing Binding Element Essentials

    We're back to the channel development series for another pair of days. When I left off, I promised to talk a bit about writing binding elements and channel managers. Today's article is about writing binding elements and tomorrow's article is about writing channel managers. These articles expand on the checklist items for the steps you have to take while writing a custom channel. To keep things simple, I'm only going to talk about the client-side part of the equation. Where needed, I'll point out that there is an equivalent server-side piece that you need to implement as well. To get a minimally working binding element for a client channel, you need to think about what you're going to do in four particular methods. CanBuildChannelFactory is how you plug into the evaluate step of the channel construction process. This method allows consumers of your channel to validate whether construction is going to succeed without actually performing the build process. You should put your validation in a common place rather than duplicating it between the evaluate and build stages. It will save you a lot of trouble whenever you update your channel. There's a corresponding method for the evaluate stage on the server. BuildChannelFactory is how you plug into the build step of the channel construction process. This method produces the channel manager object used by the next layer of the build process. Primarily what you're doing here is copying settings from the binding element to the channel manager so that future changes to the binding element don't affect existing channels. There's a corresponding method for the build stage on the server. GetProperty is a query interface for dynamically discovering information about the channel. Any properties you don't recognize should be passed to the inner binding element so that channels further down in the stack have a chance to respond. I'll have more details about the interfaces you should implement with GetProperty later. Clone produces an exact copy of the binding element. You should implement Clone by creating a copy constructor and doing all of the work in the constructor. Clone will be called many times during the evaluate and build processes. It is essential that modifying the cloned binding element does not affect the original binding element. Next time: Writing Channel Manager Essentials Read More...
  • Channel Managers

    Last time, we left off the channel construction process at the end of the design stage. During the design stage, everything is still in an unmolded and configurable state. At the end of the design stage, the construction process flips from a configuration mode to a runtime mode. The runtime stage has fixed all of the design settings and is in an operational state. Here were the products so far in the construction process starting from the service. Service Service endpoint Service endpoint contract Service endpoint transfer contract (binding) Binding design settings Realization of binding design settings (binding elements) From the binding elements we can produce two objects called channel managers. A channel manager is something that can produce communication channels on demand. One type of channel manager is the channel factory. Channel factories create communication channels that initiate a connection or message send. The other type of channel manager is the channel listener. Channel listeners create communication channels in response to a message or connection attempt. Channel factories generally live in client applications and channel listeners generally live in service applications. The channel manager is the first product in the construction process that performs network operations and can represent a network object. For example, channel managers may contact security servers in preparation for creating communication channels or allocate resources such as a TCP listener socket. The creation of communication channels is controlled by the user for channel factories and essentially controlled by the system for channel listeners. You have to initially start the channel listener but further action is taken in response to messages or connections arriving from other machines. Communication channels are the conduits for sending and receiving messages. The final product of the construction process is one of these channels. For those of your following along, that means to produce a custom channel you will need to write the binding, the binding element, the channel managers, and the channel. All of these were included in the channel writing checklists (the binding was the only one on the optional checklist). When we get to the next two articles in the tour series, the coverage will be on writing the binding element and channel managers. Next time: Responding to GetProperty Read More...
  • Channel Bindings

    We're back to the channel development tour for another pair of articles. Today's article is the first of four in this segment on channel construction. The first half of the segment is background and the second half of the segment talks about code. In each half, there is an article on bindings and an article on channel managers. After we're done with this segment, everything else in the series deals directly with implementing the channel interfaces. Channels go through a somewhat complicated construction process . This construction process essentially has three stages: design, evaluate, and build. Bindings are the typical user-accessible part of the construction process and correspond to the design stage. We have to take a few steps back before it becomes clear how bindings fit into the model. You have a service. Your service has endpoints that enforce a particular contract for exchanging data. One part of your endpoint's contract is the protocol for how the client and server can send each other a message. The implementation of a protocol contract is called a binding. There are many ways to build this implementation, including through configuration files or writing code. Bindings expose design settings that allow the user to configure various aspects of the network protocols. The binding is a rough equivalent to the channel stack, a composition of all of the chosen protocols. Given a specific set of design settings, the binding can produce a set of binding elements that correspond to those settings. Each binding element is a rough equivalent to one channel in the channel stack. We'll see some examples latter where that isn't true, but it's generally the case. We'll stop here in the process for now because at the next step we'll be producing the channel managers that are the subject of tomorrow's article. The binding and binding element expose methods that allow us to perform the evaluate and build stages. The evaluate stage allows the user to query whether the chosen design settings of the binding make sense for building a channel manager. This is a cheap way of verifying the build process without having to actually initiate a build. The build stage locks the design settings of the binding in place and produces the corresponding channel manager. From the channel manager, the build process is going to continue a little bit farther until we have actual channels. Next time: Channel Managers Read More...
  • Channel Writing Checklist (Optional)

    Let's fill in some of the spaces around yesterday's checklist with a list of additional features for a custom channel. Nothing that's been added to this list is required to actually send or receive messages. By doing the things listed here, you can enable some additional scenarios and make your channel easier to use. However, if you're looking to write a channel as cheaply as possible, then these are the features that you might consider cutting. I'll summarize the previous list using italics and interlace the descriptions of the new checklist items. Understand why you're writing a channel. Identify whether the channel you need is a protocol channel or a transport channel. Identify the channel shapes that your channel needs to be able to surface. Write a binding element so that your channel can plug into the build process. Add configuration support to your binding element. Configuration allows the settings of your binding element to be specified through XML files rather than through imperative code. You implement this configuration support by writing a binding element extension that duplicates the property settings of your binding element in a format that can be picked up by the configuration system. You will quickly grow tired of performing this duplication by hand and start thinking about how this process can be done automatically instead. Write a standard binding that demonstrates the proper usage of your binding element. A standard binding represents the stacks of binding elements for your core scenarios along with the most commonly used configuration settings for those binding elements. Creating a standard binding allows people to frequently make use of your channel without having to write a custom binding of their own. Support generating and consuming policy assertions that describe the capabilities of your binding element. Policy assertions allow you to advertise particular features of your channel so that the two sides can coordinate ahead of time about how the channel stack should be constructed. Policy support is implemented through a pair of interfaces for policy import extensions and policy export extensions. Write a client channel factory that can produce instances of your channel for use by client applications. Write a service channel listener that can produce instances of your channel for use by service applications. Write channel instances to cover each of the supported channel shapes. For transport channels, add a description of your supported Read More...
  • Channel Writing Checklist (Required)

    This pair of articles marks the checkpoint between the "big picture" introductory segments and the segments where we actually start getting down into the code. The transition is going to be gradual so there's still some philosophy left, particular around the construction of bindings and binding elements. However, the objective of the articles is going to be less about how to think about the system and more about how to think about the code. Here, we get into a checklist of the bare minimum necessary to write a channel. The first few items come from past topics, and you can use the rest as a roadmap of where we're going to go next. Understand why you're writing a channel . Forever more in this series, I'm assuming that you've looked at the other extensibility points and decided that writing a channel is the best way to solve your problem. Identify whether the channel you need is a protocol channel or a transport channel . Identify the channel shapes , one or more, that your channel needs to be able to surface. Write a binding element so that your channel can plug into the build process. The binding element is going to take one of the supported channel shapes and return the factory object that produces channels. Writing a binding is not required as you can always use your binding element in a custom binding. The binding element is also going to hold all of the configurable settings for your channel. Write a client channel factory that can produce instances of your channel for use by client applications. If you have an integration scenario where you're only writing channels for use in a web service, then you can skip this step. For example, if the client is going to be a web browser that doesn't use WCF, then you might not ever have a need to create client channels. Write a service channel listener that can produce instances of your channel for use by service applications. If you have an integration scenario where you're only writing channels for use in a client, then you can skip this step. For example, if you are trying to communicate with an existing mainframe service, then you're only going to produce channels to bridge the connection between WCF and the other system. Write channel instances to cover each of the supported channel shapes. I think it's easier to have separate classes for each channel shape that all use a central communication library. However, you may find it easier to implement multiple channel shapes in a single class. I've put the channel Read More...
  • Channel Shapes

    I was looking through the archives the other day and found that the original article on channel shapes is actually still accurate despite having come out a year ago. It's interesting to step forward in time and watch as things become more and more like what actually was released. I've done similar walks through a longer history of the product, although you have to patiently track through whole concepts appearing and disappearing. In celebration of this bit of history, I decided to let last year's article stand. I did have a new picture in the channel dev tour drawing style that I wanted to include though. Update : I'm not sure when the count got off track, but this article turned out to be a day later than one year. Fortunately, now that the product is out, the things that I'm writing about are unlikely to change on a daily basis. Next time: Extracting Content Types Read More...
  • Message Flow Interception Points

    We've been looking at the flow of messages ( Part 1 and Part 2 ), but have never stopped along the way to look at the extensibility points where you can plug in your own code. Being a highly-extensible framework, WCF has piles and piles of these extensibility points. Some of the extensibility points are more likely than others to be confused with the proper use of channels. I'm just going to list out a sequence of points, not intended to be exhaustive, where you can execute custom code in the message flow. We'll go in chronological order from the client to the server to match the earlier articles. Client code- Obviously, you have total control here over when service methods get called. Generated client proxy- If your proxy object is generated ahead of time instead of dynamically, then you can extend the proxy to run code whenever a particular service method is invoked. Message serializer- The message serializer sits below the proxy and converts CLR objects into an XML message. Client message inspector- The client-side message inspector lives above the channel stack and is the first one to see the newly-generated XML message. You could alternatively have added a new channel to the top of the channel stack. Client channel stack- The channel stack has all of the protocol and transport channels that were specified in your binding. Network intermediaries- Once on the wire, anything can happen to the byte stream during transmission. Service activation- Service activation is an optional layer that automatically controls the lifetime of service processes. Service host- The host of the service actually has many extensibility points inside. You can replace the factory that is used to stamp out host instances or you can modify the behavior of the host itself. Service channel stack- The service channel stack is the receive-side collection of protocol and transport channels. Dispatch message inspector- A server-side message inspector lives above the service channel stack and functions similarly to its client-side equivalent. Dispatch operation selector- Once we've gotten the message into a particular service, we need to figure out which one of the service operations is being called. Message deserializer- Message deserialization reverses the serialization process by converting an XML message back into CLR objects. Dispatch parameter inspector- Parameter inspection is the equivalent of a message inspector for the CLR objects that get produced during deserialization. Dispatch Read More...
  • Flow of Messages, Part 2

    Continuing from last time, we were looking at the flow of a message during a service call. We left off at the point where the service client had just dropped a message off to the network. Today, we're going to follow that message up through the completion of the service call. This is essentially going through the process of a one-way call. Right from the start, we hit a fork in the road. Either the service is running (because it's always-on or something has previously told it to turn on) or we need to start the service in response to the message arriving. Let's assume that we need to activate the service because everything afterwards is the same for the two paths. For each protocol that we want to activate on, the transport has a corresponding component that serves as the activation listener. The job of the activation listener is to listen for the first message destined for a service, start that service up, and then get out of the way. The details of activation aren't going to be used in this series, which is fortunate because it takes a long time to explain the process. Instead, we're going to jump ahead to the point where the service has come up. The activation listener does not actually process any messages. Once the service has been started, the first message goes to the transport just like any other message. The message then passes through the transport and protocol channels, undoing any of the processing that was performed on the client side. At the bottom of the channel stack, the transport channel takes the stream of bytes used for network transmission and converts that stream back into an XML message. The message passes up through the stack of protocol channels, which again apply any number of transformations along the way. At the top of the channel stack, we need something to reverse the process that the proxy performed to translate our method call into an XML message. This component is called the dispatcher because it needs to pull messages out of the pipeline and route each message to the appropriate service call. Back on the client side, the proxy took information about the service method being invoked and encoded that information into the message as addressing headers. The dispatcher looks at those addressing headers, finds the appropriate method to invoke, converts the payload of the message back into method parameters, and finally calls the method on the service instance. We have a quick break coming up, but when this series next continues, Read More...
  • Flow of Messages, Part 1

    In the channel development series so far, we've just been looking at channels. I've already mentioned that you should consider using other extensibility points instead of channels when that's cost-effective. However, it has so far been left a mystery what those other extensibility points are. This series is not about documenting extensibility points other than channels. I will give a brief outline though just so you have some keywords to go off researching on your own. For illustration, I'm going to demonstrate the basic pattern of messaging that takes place during a service call. Today's part of the illustration covers the client side of that messaging. We will end today with a message being put on the network. The next part of the illustration covers the server side of messaging. Even though most service calls are two-way, I'm only going to examine this single direction. I'll let you imagine the exact same process happening in the opposite direction. After we go through the message flow, I'll list off some of the extensibility points that the message passed along the way. Here is the client side portion of the message flow. I have a single web service off running somewhere else in the world. The exact details of how we connect to that web service are unimportant. I have previously gotten a contract that describes some service operations and directions for contacting the service. Using this contract, I have designed a client application that wants to invoke some of the service operations. I don't want to have to worry about messaging when invoking a web service operation. Method calls are easy to understand for someone that has any programming background. Networking is something that is much harder to understand. I would like for the message exchange between the client application and the web service to look like a method call. The proxy is a combination of dynamically-generated and framework code that gives service methods the illusion of being ordinary methods. We have taken the service contract and instantiated a type that has all of the service operations exposed as type members. Invoking one of the generated type members using a method call triggers the framework to send a message to the web service. The remaining processing on the client side is to push out that message. The message will pass down through the stack of protocol channels, having any number of transformations applied to it. At the bottom of the channel stack, the transport channel takes Read More...
  • Channels Illustrated

    In the channel development series last week, we looked at the characteristics of channels (protocol channels, transport channels, and why you would write a channel at all). Let's use a specific example to illustrate those points. Although the protocol for reliable messaging is quite complex, the basic intent of the channel can be described quite simply. We'll keep the discussion simpler by only talking about the send side of the server response. You can map this yourself to the client side or to receiving messages, but this example doesn't need a lot of details to get the point across. Here's a channel stack that contains the reliable messaging channel. When the server sends a message out to the client, that message passes through the upper protocol channels in the channel stack. Those protocol channels can create, alter, or destroy messages along the way, but let's say that the message arrives intact to the reliable messaging channel. The reliable messaging channel first makes a copy of the message just in case delivery fails in the future. The reliable messaging channel then sends the message down through the remaining protocol channels. Again, we'll assume that nothing happens along the way; the message gets to the transport and is sent over the network. Sometimes, despite the best efforts of this process, the client never receives the message. In that case, the reliable messaging channel will produce another copy of the message from its store and send it again. Eventually, the client will either acknowledge receipt of the message or the two sides will decide to give up due to their inability to communicate. When the message is acknowledged, the reliable messaging channel throws its copy away as the message is no longer needed. Let's check against the criteria for writing channels to see if a channel was really needed to perform reliable messaging. Did we need a new component that interfaces with the network? No, there was some other component in the channel stack that handled the network for us. Did we need to establish a pattern of message exchange? Yes, the pattern of retries and acknowledgement is something that's different from the exchange inherent in a service call. Did we need to have a protocol for expressing the messages? Yes, although we didn’t talk about the details of that protocol in this example. We need some way of describing what data is, what acknowledgments are, and when retries are occurring. Did we need something other than a one-to-one Read More...
  • Transport Channels

    Let's shift gears for a bit and talk about transport channels now as opposed to protocol channels. Everything that was said yesterday for channel stacks is still true when we add transport channels to the picture. Everything that was said yesterday for protocol channels is essentially going to be reversed. Here are the essential points that change when we move from protocol channels to transport channels. Protocol channels have two sides: an inner and an outer channel. Transport channels have one side. The inner end of the transport channel connects to the network. Obvious corollary : Protocol channels move messages up and down the channel stack. Transport channels move messages to and from the network. More obvious corollary : Every channel in the channel stack but the bottommost one is a protocol channel. The bottommost channel in the channel stack is a transport channel. Protocol channels work on messages that are XML InfoSets. Transport channels operate on a stream of bytes. As we go through the architecture, you'll notice that transport channels are the only time during messaging that we have actual bytes. This is a necessity as traditional networking interfaces, such as sockets, have no idea how to send an XML message. The only data type that these interfaces rationalize about is byte arrays. The transport channel is the component that is responsible for converting between XML messages and byte streams. There is a standard pattern for delegating this behavior from transports to an external component called a message encoder. A message encoder is an interface that allows third-party developers to plug conversion functionality into a transport. You can choose to either use or ignore this model, although I'd strongly suggest supporting encoders if your transport permits multiple byte encodings for an XML message. The transport channel is also responsible for doing any post-processing on the byte stream. For example, there is a common step called framing in which the payload data is embedded inside a structured format for sending messages. Unlike message encoders, there is no standard interface for applying framing to a byte stream. The current transports that support framing build their framing protocol directly into the transport channel. We're going to take a break from the channel development series for a day tomorrow. When we come back, there will be some catch-up for illustrations and then we go directly into the second topic to overview WCF architecture. Read More...
  • Protocol Channels

    There are only two kinds of channels in the world. Today we'll talk about protocol channels. Tomorrow we'll talk about transport channels. Transport channels move data to and from the network Protocol channels move data between the application and transport channel The name "protocol channel" for the second group is a lie. Of the channels we shipped in the product, the most common representative for the second group happens to be protocols. That doesn't mean that every channel in the second group has to an implement a protocol though. The key distinction for the second group is really "moves data between the application and transport channel". In other words, the second group is made up of everything that is not a transport channel. However, if you're following the advice from yesterday about when to write a channel, then I think you'll find that most of the channels that you write are either transport channel or implement some kind of protocol. A channel has two ends to it. The outer end points to the application. The inner end points to the network. If you start stitching together channels end-to-end, you come out with something called the channel stack. The inner end of one channel links to the outer end of another channel. In relative terms, these are the inner and outer channels of the channel that we're looking at. Obviously, we run into a problem if we keep following down the path of inner (or outer) channels. If we follow down the path of inner channels, eventually we'll hit a channel that has no other channel on the inner end to pass data to. That innermost channel is the transport channel that we'll talk about tomorrow. If we follow up the path of outer channels, eventually we'll hit a channel that has no other channel on the outer end to pass data to. Beyond the outermost channel is the application. In between the outermost channel and user code is a large mass called the service model. We'll have a brief look at the architecture of the service model in a few days. Otherwise, there's nothing particular distinctive about the outermost channel. Every channel along the way, except the innermost channel, is a protocol channel. The job of a protocol channel is to pump data between its inner and outer sides. That data is a structure called the XML InfoSet . An infoset is a standardized concept but really you don't have to understand the standard to make use of it. The pump that acts on these infosets is any arbitrary code you care to write. As a channel Read More...

Copyright © 2006 Microsoft Corporation. All Rights Reserved. | Terms of Use | Privacy Statement | Contact Us