Reputation: 24067
public interface IConsoleData
{
double GetCurrentIndicator();
}
public class IConsoleDataImpl : IConsoleData
{
public double GetCurrentIndicator()
{
return 22;
}
}
[ServiceContract]
public interface IMBClientConsole
{
[OperationContract]
IConsoleData GetData();
}
public class MBClientConsole : IMBClientConsole
{
public IConsoleData GetData()
{
return new IConsoleDataImpl();
}
}
class Log
{
public static void initialize()
{
using (ServiceHost host = new ServiceHost(typeof(MBClientConsole),
new Uri[]{
new Uri("net.pipe://localhost")
}))
{
host.AddServiceEndpoint(typeof(MBClientConsole),
new NetNamedPipeBinding(),
"PipeReverse");
host.Open();
// TODO: host.Close();
}
}
}
And when AddServiceEndpoint
is called I receive
The contract type Commons.MBClientConsole is not attributed with ServiceContractAttribute. In order to define a valid contract, the specified type (either contract interface or service class) must be attributed with ServiceContractAttribute.
But as you can see from my code interface is attributed with ServiceContract attribute. Why VS claims that it doesn't and how to fix the problem?
Updated listing below:
public interface IConsoleData
{
double GetCurrentIndicator();
}
public class IConsoleDataImpl : IConsoleData
{
public double GetCurrentIndicator()
{
return 22;
}
}
[ServiceContract]
public interface IMBClientConsole
{
[OperationContract]
IConsoleData GetData();
}
public class MBClientConsole : IMBClientConsole
{
public IConsoleData GetData()
{
return new IConsoleDataImpl();
}
}
class Log
{
private ServiceHost _host;
public void initialize()
{
_host = new ServiceHost(typeof (MBClientConsole),
new Uri[]
{
new Uri("net.pipe://localhost")
});
_host.AddServiceEndpoint(typeof(IMBClientConsole),
new NetNamedPipeBinding(),
"PipeReverse");
_host.Open();
System.Threading.Thread.Sleep(1000000);
// TODO: host.Close();
}
}
Client:
public interface IConsoleData
{
double GetCurrentIndicator();
}
[ServiceContract]
public interface IMBClientConsole
{
[OperationContract]
IConsoleData GetData();
}
class Program
{
static void Main(string[] args)
{
ChannelFactory<IMBClientConsole> pipeFactory =
new ChannelFactory<IMBClientConsole>(
new NetNamedPipeBinding(),
new EndpointAddress(
"net.pipe://localhost/PipeReverse"));
IMBClientConsole pipeProxy =
pipeFactory.CreateChannel();
while (true)
{
string str = Console.ReadLine();
Console.WriteLine("pipe: " +
pipeProxy.GetData().GetCurrentIndicator());
}
}
}
I still receive CommunicationException "There was an error reading from the pipe: The channel was closed. (109, 0x6d)."
Upvotes: 0
Views: 1950
Reputation: 52290
change
host.AddServiceEndpoint(typeof(MBClientConsole),
new NetNamedPipeBinding(),
"PipeReverse");
to
host.AddServiceEndpoint(typeof(IMBClientConsole),
new NetNamedPipeBinding(),
"PipeReverse");
the second needs the Service-Contract (=Interface) not the implementation. Sometimes they are the same but not here.
With
using (ServiceHost host = new ServiceHost(typeof(MBClientConsole),
new Uri[]{new Uri("net.pipe://localhost")}))
you say WCF what "object" to create (MBClientConsole
) when the service is called (and the base-Address of the service) but with the AddServiceEndpoint
you tell WCF what Service-Contract to expose. I hope you can make any sense from that ;)
You have a bug in your code:
public static void initialize()
{
using (ServiceHost host = new ServiceHost(typeof(MBClientConsole),
new Uri[]{new Uri("net.pipe://localhost")}))
{
host.AddServiceEndpoint(typeof(IMBClientConsole),
new NetNamedPipeBinding(),
"PipeReverse");
host.Open();
// TODO: host.Close();
}
}
since you are using using(Service host ...
the host object will be disposed if you leef the Initialize-Method. I guess you copied this from a ConsoleHost-Example. Move the host into a field and use something like this:
class Log
{
ServiceHost _host;
public void Initialize()
{
_host = new ServiceHost(typeof(MBClientConsole),
new Uri[]{new Uri("net.pipe://localhost")});
_host.AddServiceEndpoint(typeof(IMBClientConsole),
new NetNamedPipeBinding(),
"PipeReverse");
_host.Open();
}
public void Close()
{
_host.Close();
_host.Dispose();
}
}
REMARKS: you made everything static (copied as I said) - I removed this. You might even think about implementing IDisposable (recommended) but I will leave this to your. You have to use this slightly different like
var log = new Log();
log.Initialize();
and before quiting your program:
log.Close();
Upvotes: 5