17

I have both ends of a bi-directional connected Stream, which I want to do some communication over. The underlying implementation behind the stream isn't important, I want to work at the Stream level...

Rather than implement my own communications protocol for the stream, I want to use all of the existing WCF goodness to wrap the existing stream with with a bi-directional (request/response + callback) WCF communications channel.

My question is, how can I go about doing this...?

UPDATE:

I've gone down the path of implementing a custom transport. I've got this working, but I'm still not totally happy with it...

I've implemented an IDuplexSessionChannel to wrap the stream, along with appropriate IChannelFactory and IChannelListener, and a Binding Element for creating the channel factories. Now, I just pass through the connected stream, and eventually pass these into the transport channel when it is created.

So, I can create the client proxy for accessing the service via the stream as follows:

var callback = new MyCallback();
var instanceContext = new InstanceContext( callback );
var pipeFactory = new DuplexChannelFactory<IMyService>( instanceContext, new StreamBinding(clientStream),
                                                        new EndpointAddress("stream://localhost/MyService"));
var serviceProxy = pipeFactory.CreateChannel();

The problem I have is, it seems WCF is set on using a ServiceHost to create the server end of the channel, via a IChannelListener. In my case, I already have a connected stream, and I won't be able to listen for any more incoming connections. I can work around this, but I'd much rather not use a ServiceHost to create the server end of the channel, because I end up with a lot of obscure boilerplate and hacks to make it work.

Questions

I'm looking, therefore, for a better way to take the IDuplexSessionChannels, and wrap these into a Channel proxy at both the server and client ends.

Or maybe a different ServiceHost implementation that doesn't require a IChannelListener.

Really, the problem here is I don't want a single server, multiple client arrangement, I have a 1-1 relationship between my WCF Service and the client. Is there a correct way to instantiate one of these?

To put it yet another way, I want to create the Server-side service instance without using a ServiceHost.

Any suggestions would be appreciated at this stage.

Mark
  • 1,784
  • 16
  • 26
  • Seems like you may be confusing the role of a WCF service host and a WCF service instance. A WCF service host provides instances of a service based on the InstanceContextMode. This [blog post](http://www.danrigsby.com/blog/index.php/2008/05/23/understanding-instancecontext-in-wcf/) has a good explanation of how that works. You really can't have an instance of a WCF service without a ServiceHost providing it. The ServiceHost in turn has a dependency on a ChannelListener to manage the messaging infrastructure for it. Without it, you'd have a "deaf" ServiceHost :) – Sixto Saez Mar 08 '12 at 20:37
  • So, what I am trying to do is do the things `ServiceHost` does to create an `InstanceContext` and Service instance. `ServiceHost` must do this when it accepts a new incoming connection. I already have the connection established, so I want to skip the listening part. Surely this isn't *impossible*...? – Mark Mar 09 '12 at 08:41
  • @Mark To me this eems like taking an existing tunnel and building another tunnel to contain it... WCF was not built for this kind of stuff... what exactly is the problem with the existing stream (which you write is working) that let's you think using WCF will solve ? – Yahia Mar 13 '12 at 08:19
  • Ok, so I have some in-process services that are exposed through some well-defined interfaces. I want to transparently re-implement these using child processes, that communicate over inherited pipe streams. Really, WCF would just give me a nice way to implement the service calls, fault contracts, etc., without having to roll my own messaging subsystem over the pipes. I've rolled my own before in C++, but I was hoping for some help from .NET doing the same. – Mark Mar 13 '12 at 13:35
  • Hi Mark, did you get any further on this? I want to do the same thing to extend the use of [Anonymous Pipes](http://msdn.microsoft.com/en-us/library/bb546102(v=vs.110).aspx) with your same use-case. Anonymous pipes, because they're the right choice, but take advantage of all the communication RPC infrastructure in WCF. – Jason Kleban May 21 '14 at 18:02
  • No, I got something working but I wasn't very happy with it. I was guilty of some extreme gold plating in this case, so I just pulled the plug on the whole idea eventually, as I didn't have that much time to waste on it. – Mark Jun 03 '14 at 11:07
  • Mmmm. When u have one already inbuilt why do u complicate? – Aravind Sep 29 '16 at 02:55

1 Answers1

1

Use a client at both ends. You will need to define your contracts carefully though. If you have ClientA and ClientB at either end of the stream, when ClientA sends a request, ClientB will expect it to look like what it sees as it's defined callback contract and vice versa.

MattC
  • 373
  • 1
  • 6
  • I'm going to accept this answer, as I think it's probably correct (at least, it makes sense that it would work). I haven't tried it, though, so YMMV. – Mark Sep 19 '19 at 11:27