Welcome to Windows Communication Foundation (WCF)
Top Tasks :

WCF Team Bloggers

Browse by Tags

All Tags » Transports   (RSS)

  • Building with Encoders

    The basis of a channel stack is that there is a series of objects that share a common interface for communication. This leaves message encoders with something of a problem as the primitive operations for encoding and decoding messages are different than the primitive operations for sending and receiving messages. Message encoders avoid this problem by being contained within a channel rather than acting as a peer in the channel stack. However, this is different than the model used for bindings, which make the message encoding binding element a peer of the other channel binding elements. To make things harder, bindings use a "no lookahead" construction process where constructing an object cannot speculate about future construction by looking into the unprocessed information in the binding. That results in a subtle dance between a message encoder and a channel that wants to use a message encoder. During the construction process, a binding gives you only a context for storing computed information and the ability to initiate the next phase of the construction process. When we go to build a message encoder, it's not possible to actually build anything because the channel that will hold the message encoder doesn't exist yet. The message encoder doesn't know how or why it is going to be used. Instead, what a message encoding binding element does to build is add itself to the BindingParameters in the context. The message encoding binding element then initiates the next phase of the construction process. At some point in the future, a channel may look at the context to see if it contains a previously saved binding element, which can now be built. The delay in instantiation is what allows channels to have a different order for physical containment than the logical order of the binding elements. Next time: Quotas for Copying Messages Read More...
  • TIBCO Announces WCF Integration

    At their user conference in San Francisco yesterday, TIBCO announced two integration initiatives to bring the TIBCO and Microsoft platforms closer together. TIBCO is developing a TIBCO EMS transport channel for WCF. Although Microsoft doesn't have a formal certification process for releasing third-party WCF components, I got to do some code and design reviews over the last few months with the TIBCO developers to understand the work that they are doing. I am very pleased that it was possible to make TIBCO EMS fit naturally into the WCF model. This integration work benefits both Microsoft and TIBCO customers by expanding the reach of applications on each platform. I fully support the partner ecosystem in delivering WCF components and connectivity options that go beyond what Microsoft provides in the framework. TIBCO is also going to be making use of Silverlight for development and deployment of Internet applications. Silverlight allows developers to reuse much of the tooling and knowledge that they have from desktop development when creating browser-based applications. Read More...
  • The Pipe DACL

    When a named pipe channel listener creates a new named pipe it has to supply a discretionary ACL that describes who can connect to the pipe. Here is how that DACL is constructed: An access control entry is added to deny GENERIC_ALL access to the well-known network SID (S-1-5-2). Access control entries are added to allow GENERIC_READ and GENERIC_WRITE access to a list of SIDs that is defined on the binding element. The default is to allow the well-known world SID (S-1-1-0). Since this list is an internal setting, you will almost always be using the default. An access control entry is added to allow GENERIC_READ and GENERIC_WRITE access to the well-known creator owner SID (S-1-3-0). And that's how the DACL gets built. There are a few other settings as well required to create the pipe if you're interested in their values. The pipe is bidirectional (PIPE_ACCESS_DUPLEX), data is written to the pipe as messages (PIPE_TYPE_MESSAGE), data is read from the pipe as messages (PIPE_READMODE_MESSAGE), we use overlapped IO (FILE_FLAG_OVERLAPPED), and if this is the first pipe created by the listener, then we need to say that more pipes are coming (FILE_FLAG_FIRST_PIPE_INSTANCE). Next time: Writing Multiple Detail Elements in Faults Read More...
  • Mapping Credentials to Authentication Schemes

    You may have noticed that an HTTP binding is configured with an HttpClientCredentialType whereas an HTTP binding element is configured with an AuthenticationScheme. How are these two settings related? If you want to switch between a custom binding and a standard binding for HTTP, then you need to know how to do the translation. Here's how client credentials map to authentication schemes: HttpClientCredentialType.None becomes AuthenticationSchemes.Anonymous HttpClientCredentialType.Certificate also becomes AuthenticationSchemes.Anonymous. Certificates are used with HTTPS rather than as authentication credentials on top of HTTP. This will be caught in validation if you try to use certificates with the TransportCredentialOnly security mode. HttpClientCredentialType.Basic becomes AuthenticationSchemes.Basic HttpClientCredentialType.Digest becomes AuthenticationSchemes.Digest HttpClientCredentialType.Ntlm becomes AuthenticationSchemes.Ntlm HttpClientCredentialType.Windows becomes AuthenticationSchemes.Negotiate Translation works the same way with proxy credentials and the proxy authentication scheme except that proxies don't have to worry about the issue with certificates. Next time: Get a Real XML Parser Read More...
  • Controlling HTTP Connection Limits

    I need to make many simultaneous HTTP calls to the same service from my client application. How do I increase the limit on the number of HTTP connections? This setting isn't available on any of the bindings or binding elements but the default limit can be set through the DefaultConnectionLimit property on System.Net.ServicePointManager. This will change the limit for every server you want to connect to. Alternatively, you can control the connection limit very granularly through configuration. < system.net > < connectionManagement > < add address ="..." maxconnection ="2" /> </ connectionManagement > </ system.net > The address can be for a particular HTTP address or for a plain machine name. Use the wildcard character * for the address to set the default connection limit through configuration. If a request can match against more than one of the configuration entries, then the most specific entry is the one that will be used. Next time: Mapping Credentials to Authentication Schemes Read More...
  • Concurrent Channel Performance

    Being thread-safe is different than being concurrent. The channel interfaces are thread-safe so that multiple callers can use them at the same time without getting garbled messages. However, if multiple callers try to send messages on a single channel at the same time then a few different things might happen. The channel might be fully concurrent and process the sends in an overlapped fashion. The channel might be partially concurrent and process a limited number of the sends at a time. The other sends are blocked until one of the earlier requests completes. The channel might be singly concurrent and process the sends in a sequential fashion. A connection-oriented channel like TCP tends to be singly concurrent. Interleaving messages requires having a sophisticated framing protocol and the performance cost is rarely worth handling this special case. Datagram channels on the other hand tend to be at least partially concurrent. For example, HTTP in theory is fully concurrent to any degree that you'd like but the HTTP specification recommends limiting clients to two connections to any particular server, resulting in partial concurrency. Whenever you have less than full concurrency you run the risk of deadlock with certain application designs. That's because the logical operation order of the application might say that caller 1 must complete a send before caller 2 can complete, but the physical operation order of the channel says that caller 1 cannot start a send before caller 2 completes. I've seen customers encounter this problem when using HTTP and callbacks. The original request is waiting for the callback operation to complete but the callback thread cannot make any progress because all of the connections are tied up by existing callers, such as the original request. This is a case where the performance gain of sharing connections has led to unsafe behavior. The solution is to increase the concurrency of the system so that at least one call from any of the ongoing chains of operations can complete (there can be callbacks on top of callbacks in complicated knots so the problem is not as simple to solve as increasing the concurrency factor to two). Concurrency can be increased directly at the networking level or by isolating networking resources into separate pools at the application level. Next time: Windows and UPN Format Credentials Read More...
  • Always Begin with Accept

    Inside a service, there's a fundamental loop running whose job it is to create channels for the incoming connections to the service. There's another loop that runs later, which you may argue is equally fundamental, that reads messages from each channel to determine the actual service invocation. Every one of these service requests though was preceded at some point by a channel being accepted (one channel may produce multiple requests of course). Depending on how things are configured, the service may be running a transactional loop or a non-transactional loop. The transactional loop runs when the service needs to create its own transaction for reading messages. As a custom channel author, the two loops have different implications for how your channel gets used. In the non-transactional case, the service sits in a loop calling BeginAcceptChannel on the topmost channel listener. This loop continues until the listener fails to give back a channel or the listener faults. The loop pauses if a quota is reached that prevents more channels from being accepted, but the loop can later be restarted when the quota is no longer an issue. In the transactional case, the service first sits in a loop calling WaitForChannel. When WaitForChannel completes, the loop creates a new transaction and calls AcceptChannel. The use of WaitForChannel is an optimization to reduce the number of unnecessary transactions that get created. The loop will later complete or abort the transaction as appropriate but otherwise functions very similarly from this point. Next time: SOAP Extensions Read More...
  • Creating Sessions over HTTP

    I've got a sessionful contract that I want to use with HTTP. How do I get the HTTP transport to produce a sessionful channel shape? The basic design principle of channels is that they produce whatever channel shape is their natural message exchange pattern. For HTTP, the natural message exchange pattern is request-reply. This means that if you want any other channel shape, then you need to apply a layered channel that changes the message exchange pattern. That is the approach regardless of whether you want to change the channel shape to one-way, duplex, or a sessionful channel. There are no built-in HTTP specific additions to create sessionful channels. We have a sample channel that demonstrates creating a session based on HTTP cookies . There are several general-purpose protocol channels that provide sessions, such as security and reliable messaging. However, this entire line of conversation tends to indicate a fundamental flaw in thinking. A session has the semantic meaning of correlating messages together according to some principle of relationship. Sessionful services use the relationship to treat the session of messages as a connected unit. The meaning of that session ought to be a more significant factor than whether some contract has been previously declared to know about sessions. If you are scrounging around to come up with any possible session to get a service working, then something is probably wrong. Next time: XML Support Read More...
  • Adding HTTP Headers

    Why doesn't anything happen when I try to add HTTP headers from a message encoder? The problem here is a basic issue of timing. Recall the interface contract that a message encoder has with its transport. The transport receives a message from the next channel up in the channel stack, does some processing on the message, and calls WriteMessage on the message encoder when it wants to write out the message body. The message encoder does not necessarily see all of the message content. Some message content, such as framing, is independent of the message encoding and directly handled by the transport. In fact, the message encoder may not be called at all if there is no content for it to write. HTTP headers are an example of content that is handled by the transport rather than the message encoder. The message encoding transforms the body of the message, but HTTP headers are always sent as text. In the call to WriteMessage, the message encoder does get a Message object, which has a handle to the HTTP headers. However, if you look at the format of a raw HTTP message, then you would see that the HTTP headers are completely written out before the message body is written out. When streaming an HTTP message, the headers may even be transmitted before the message body is written out. Therefore, you should guess that it's unlikely that the message encoder can do anything with the HTTP header collection because the HTTP headers may already have been transmitted. If you want to change the HTTP headers, then you should make sure that all of the changes are made before the transport is given the message. Next time: WCF Case Studies Read More...
  • Interfaces for GetProperty, Part 1

    This is more of a reference than anything else. People have asked me what interfaces do something when used with GetProperty on a binding element. Of course, a custom implementation can do whatever it wishes in its GetProperty, so I can only tell you what the standard implementations have done. Also, GetProperty is chained from one place to another. For example, if a property is not found on a channel binding element, it is likely to go off looking at lower binding elements in the channel stack, the message encoder, and so on. What's listed here is just what is specifically handled in a given implementation. I've split this list into "transports" and "everything else". The base class for transport responds to three types. ChannelProtectionRequirements (this just give the default values) MessageVersion (SOAP 1.2, WS-Addressing 1.0) XmlDictionaryQuotas (this just gives the default values) The HTTP and HTTPS transports respond to three additional types. Also, these transports automatically check against the properties of a text message encoder if you didn't specify any encoder at all. None of the other transports do this for you. ISecurityCapabilities IBindingDeliveryCapabilities TransferMode The TCP and Named Pipes transports respond to only two additional types. IBindingDeliveryCapabilities TransferMode The Peer transport responds to three additional types. IBindingMulticastCapabilities ISecurityCapabilities IBindingDeliveryCapabilities The MSMQ transports respond to three additional types. The last one only occurs for the Integration mode of MSMQ. ISecurityCapabilities IBindingDeliveryCapabilities MessageVersion (always set to None for Integration mode) Next time: Interfaces for GetProperty, Part 2 Read More...
  • Setting the Message Via

    Can I write a point-to-point router service by setting the Via property for outgoing messages? Like most things, this is going to depend on the specific behavior of the transport channel you're using, but in general the answer is no. The transport channel owns the Via property and it will stomp over whatever you write into the message headers. You do have one opportunity to set the channel's Via, which is during the creation of the channel from the channel factory. After that, the matter is out of your hands. This would imply creating a channel per message or keeping a pool of these channels around to farm out messages if you keep using the same destinations over and over. There is a different story if what you want to route to is the ultimate receiver To address instead of the Via address. You can set the To address on a per-message basis, assuming that the transport channel has implemented the ManualAddressing setting . Next time: Enabling Kerberos in IIS 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...
  • 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...
  • When to Write a Channel

    Today's article is about the tension between two simple points. Writing channels can generally be used to solve just about any problem in WCF Writing channels is generally the most time-consuming way to solve a problem in WCF The key inference that you should be taking away from this discussion follows pretty directly from these points. Just because you can go out and solve your problem by writing a channel doesn't mean that writing a channel is the right answer to your problem. How do you know if there's a more cost-effective solution to your problem than writing a channel? Well, that's always going to be a difficult question to answer because there are many very subtle points that cause solutions to explode in complexity. In contrast, channels have a very regular and ordered structure that makes it easy to reason about systems composed from channels (we'll be looking at this structure a lot more in the future). We can exploit the regularity of the channel model by identifying types of problems that work very naturally with channels and by identifying other types of problems that most likely have a better solution elsewhere. Think of this as a pocket-guide to helping you make the decision. Channels are the component in WCF that interfaces with the network. If you have to take some direct action on a network resource, either sending or receiving data, then you are typically talking about building or using a channel. Channels are the component in WCF that establish a pattern of message exchange. When you're having a conversation, there are social rules that dictate when someone can start talking. Different social situations have different sets of rules. In WCF messaging, channels provide the equivalent of these rules of exchange. Similarly, channels represent the social protocols for how to format ideas for exchange but say nothing about what ideas can be exchanged. In the most basic messaging pipeline, there is a one-to-one correspondence between messages entering and leaving the pipeline. Many of the components of WCF follow this simple pipeline model but channels do not. Channels take an arbitrary number of input messages (even zero) and produce an arbitrary number of output messages (again, even zero). Just because you have a message-processing system doesn't mean that you can't make method calls. For example, if all you want to do is execute some SQL query from within your service, then use ADO.NET. If you have built some predefined send and receive operations Read More...
  • Channel Development Tour, Part 1

    This is the start of a long series on channel development. Some of the material in the series is going to duplicate topics that I've written about in the past. That's ok. The goal of the series is to have a walkthrough that is self-contained and in one place that is easy to read through. Many of those older articles are for older versions of WCF and may differ slightly from what was shipped in the final version. Everything in this series is going to talk about the V1 version of WCF. As an added bonus, everything here should still be true in the next version of WCF and future versions after that. This is the advantage of having to live with backwards compatibility. Future versions of WCF might make it easier to do the things that I talk about, but the methods in this series should continue to work forever. In the end, it should be possible to stitch the articles in this series together into one massive blob of text although I probably won't go that far. Here's what the series is going to cover: Background on the role of channels WCF and the channel model architecture Basic walkthrough of writing channels Writing a simple protocol channel Advanced walkthrough of writing channels Writing a simple transport channel Specialty topics for writing channels The earlier topics consist of 4 or 5 articles each. The later topics consist of around 10 articles each. As you can see, this is going to be a really long series in total. To counter that, I'm not going to run articles in this series all 5 days a week. You will probably get 3 articles of this series per week mixed in with other unconnected topics. Here are the four articles in topic #1: The Introduction (that's this article you're reading now) When to Write a Channel Protocol Channels Transport Channels I'm not going to do an introduction article for each topic so topic #2 starts directly in the fifth article. Next time: When to Write a Channel Read More...
More Posts Next page »

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