{"id":36,"date":"2005-06-27T18:14:20","date_gmt":"2005-06-28T01:14:20","guid":{"rendered":"http:\/\/kennyw.com\/indigo\/36"},"modified":"2005-06-27T18:14:20","modified_gmt":"2005-06-28T01:14:20","slug":"channels-110b-ilistenerfactory","status":"publish","type":"post","link":"https:\/\/kennyw.com\/?p=36","title":{"rendered":"Channels 110b: IListenerFactory"},"content":{"rendered":"<p>At the root of a service-side stack lives an IListenerFactory.  When you <a href=\"http:\/\/winfx.msdn.microsoft.com\/library\/default.asp?url=\/library\/en-us\/indigo_con\/html\/d780af9f-73c5-42db-9e52-077a5e4de7fe.asp\">add an Endpoint<\/a> to a Service, its binding constructs an IListenerFactory stack which is responsible for receiving messages associated with that endpoint.<\/p>\n<p>In our <a href=\"\/wp-content\/indigo\/UdpSample.zip\">sample code<\/a>, IListenerFactory-related files include <em>UdpListenerFactory.cs<\/em>, <em>UdpInputListener.cs<\/em>, and <em>UdpInputChannel.cs<\/em>.<\/p>\n<h4>UdpListenerFactory<a name=\"udplistenerfactory\">&nbsp;<\/a><\/h4>\n<p>UdpListenerFactory derives from ListenerFactoryBase.   For <a href=\"http:\/\/kennyw.com\/indigo\/21\">addressing purposes<\/a>, we implement SetUri() and SetUniqueUri().<\/p>\n<p>Similar to <a href=\"http:\/\/kennyw.com\/indigo\/29#udpchannelfactory\">UdpChannelFactory<\/a>, UdpListenerFactory overrides OnOpening() and OnClosed() to setup and tear-down resources (IBufferManager, FilterTable, etc) at the appropriate points of the <a href=\"http:\/\/kennyw.com\/indigo\/18\">state machine<\/a>.<\/p>\n<p>In OnOpen() we create and bind a single Udp socket to receive datagrams.<\/p>\n<p>In OnOpened(), we begin receiving data on our Udp socket in an asynchronous loop.  As we receive data, we convert the data into Messages using the Message Encoding Framework:<\/p>\n<div class=\"code\"> message = <code class=\"classname\">UdpConstants<\/code>.MessageEncoder.ReadMessage(<code class=\"keyword\">new<\/code> <code class=\"classname\">ArraySegment<\/code>&lt;<code class=\"keyword\">byte<\/code>&gt;(buffer, 0, count), bufferManager);<\/div>\n<p>We use a <code class=\"classname\">FilterTable<\/code>&lt;<code class=\"classname\">UdpInputListener<\/code>&gt; in order to match incoming Messages to Listeners that we&#8217;ve created.   If we get a match, we dispacth the message to the UdpInputListener, which will enqueue it for a pending receive on its singleton channel (see UdpInputListener and UdpInputChannel sections below for details).  If we don&#8217;t have any matching listeners for the new message, we write a warning entry to the system Event Log, and drop the message.<\/p>\n<h4>UdpInputListener<a name=\"udpinputlistener\">&nbsp;<\/a><\/h4>\n<p>UdpInputListener is our implementation of <a href=\"http:\/\/kennyw.com\/channelinterfaces#iinputlistener\">IInputListener<\/a>.  Since the same datagram channel represents messages that come in from any number of sources, we call UdpInputListener a singleton listener. That is, we have at most one active <a href=\"http:\/\/kennyw.com\/channelinterfaces#ichannel\">IChannel<\/a> associated with this listener at a time. We only generate another one if a channel returned from our AcceptChannel() is subsequently disposed.<\/p>\n<h4>UdpInputChannel<a name=\"udpinputchannel\">&nbsp;<\/a><\/h4>\n<p>UdpInputChannel is our implementation of <a href=\"http:\/\/kennyw.com\/channelinterfaces#iinputchannel\">IInputChannel<\/a>.  It consists of a queue of incoming Messages.  UdpListenerFactory adds matching incoming messages to this queue, and these messages are dequeued by IInputChannel.Receive() calls.<\/p>\n<p>You will also notice some complexity in <em>UdpListenerFactory.cs<\/em> around the async read loop to ensure we (a) always have an outstanding read on the receiving UDP socket and (b) maximize synchronicity while not blocking threads or deadlocking. If you want further details on a particular snippet of code, let me know.<\/p>\n<p>Next up will be tying the IChannelFactory and IListenerFactory to the &#8220;ABCs&#8221; of ServiceModel by creating a custom Binding Element. I can feel the excitement building&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>At the root of a service-side stack lives an IListenerFactory. When you add an Endpoint to a Service, its binding constructs an IListenerFactory stack which is responsible for receiving messages associated with that endpoint. In our sample code, IListenerFactory-related files include UdpListenerFactory.cs, UdpInputListener.cs, and UdpInputChannel.cs. UdpListenerFactory&nbsp; UdpListenerFactory derives from ListenerFactoryBase. For addressing purposes, we implement [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[],"class_list":["post-36","post","type-post","status-publish","format-standard","hentry","category-indigo"],"_links":{"self":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/posts\/36","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=36"}],"version-history":[{"count":0,"href":"https:\/\/kennyw.com\/index.php?rest_route=\/wp\/v2\/posts\/36\/revisions"}],"wp:attachment":[{"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=36"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=36"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kennyw.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=36"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}