Answer the question
In order to leave comments, you need to log in
Why doesn't duplex WCF work?
Wrote a WCF
service and client . The bottom line is this: the client calls the Register() method on the server , which adds the client's channel to the clientChannels list so that you can then use it to call client methods. As soon as the client sends a message using the SendMessage() method , the server on each channel in the list calls the ShowMessage() method , which causes the client to print the parameter specified by the server to the console. The WCF service is hosted by a console application. All clients share the same service. In short, ServiceBehavior.InstanceContextMode = InstanceContextMode.Single , ServiceContract.SessionMode = SessionMode.Allowed, the binding is WSDualHttpBinding . The service starts and seems to work fine, but the client, when calling the Register() method, blocks and, after some timeout, throws an EndPointNotFoundException: No endpoint was listening on localhost:8733/Design_Time_Addresses/WCFDuplexServ... that could accept the message. Where is the mistake?
using System.ServiceModel;
namespace WCFDuplexServiceTest
{
// Server methods.
[ServiceContract(SessionMode = SessionMode.Allowed, CallbackContract = typeof(IClientCallback))]
public interface IMessageService
{
[OperationContract(IsOneWay = true)]
void Register();
[OperationContract(IsOneWay = true)]
void SendMessage(string message);
}
// Client methods.
public interface IClientCallback
{
[OperationContract(IsOneWay = true)]
void ShowMessage(string message);
}
}
using System.Collections.Generic;
using System.ServiceModel;
namespace WCFDuplexServiceTest
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class MessageService : IMessageService
{
private List<IClientCallback> clientChannels = new List<IClientCallback>();
private int numberOfUsers = 0;
public MessageService() { }
public void Register()
{
clientChannels.Add(OperationContext.Current.GetCallbackChannel<IClientCallback>());
numberOfUsers++;
}
public void SendMessage(string message)
{
foreach (var channel in clientChannels)
channel.ShowMessage(message + string.Format("/nPeople in server: {0}", numberOfUsers));
}
}
}
using System;
using WCFDuplexServiceTest;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace WCFDuplexServiceTestHost
{
class Program
{
static void Main(string[] args)
{
ServiceHost serviceHost = new ServiceHost(typeof(MessageService), new Uri("http://localhost:8000/WCFDuplexServiceTest/"));
try
{
serviceHost.AddServiceEndpoint(typeof(IMessageService), new WSDualHttpBinding(), "MessageService");
serviceHost.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });
serviceHost.Open();
Console.WriteLine("Service started; press ENTER to terminate.");
Console.ReadLine();
serviceHost.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine("Something wrong: {0}", ce.Message);
serviceHost.Abort();
}
}
}
}
using System;
using WCFTestServiceClient.MessageService;
using System.ServiceModel;
namespace WCFTestServiceClient
{
class Program
{
static void Main(string[] args)
{
MessageServiceClient client = new MessageServiceClient(new InstanceContext(new MessageServiceHandler()), "WSDualHttpBinding_IMessageService");
client.Register();
client.SendMessage("How many are people online?");
}
}
internal class MessageServiceHandler : IMessageServiceCallback
{
public void ShowMessage(string message)
{
Console.WriteLine("Server response: " + message);
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" />
</system.web>
<!-- Во время развертывания проекта библиотеки служб содержимое файла конфигурации необходимо добавить к файлу
app.config на узле. Файлы конфигурации для библиотек не поддерживаются System.Configuration. -->
<system.serviceModel>
<services>
<service name="WCFDuplexServiceTest.MessageService">
<endpoint address="" binding="wsDualHttpBinding" contract="WCFDuplexServiceTest.IMessageService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/Design_Time_Addresses/WCFDuplexServiceTest/Service1/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!--Чтобы избежать раскрытия метаданных,
до развертывания задайте следующим параметрам значение "false".-->
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
<!-- Чтобы получить сведения об исключениях в ошибках для отладки,
установите ниже значение TRUE. Перед развертыванием установите значение FALSE,
чтобы избежать разглашения сведений об исключении -->
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_IMessageService"
clientBaseAddress="http://localhost:8000/WCFTestServiceClient/" />
</wsDualHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8733/Design_Time_Addresses/WCFDuplexServiceTest/Service1/"
binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IMessageService"
contract="MessageService.IMessageService" name="WSDualHttpBinding_IMessageService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
Answer the question
In order to leave comments, you need to log in
The firewall may have blocked listening to:
localhost:8733/Design_Time_Addresses/WCFDuplexServ...
Write more clearly on the server.
var serviceHost = new ServiceHost(typeof(MessageService));
var uri = new Uri("http://localhost:8000/WCFDuplexServiceTest/MessageService")
serviceHost.AddServiceEndpoint(typeof(IMessageService), new WSDualHttpBinding(), uri);
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question