Написал службу и клиент
WCF. Суть такова: клиент вызывает на сервере метод
Register(), который добавляет канал клиента в список
clientChannels, чтобы потом с его помощью можно было вызывать методы клиента. Как только клиент посылает сообщение методом
SendMessage(), сервер на каждом канале из списка вызывает метод
ShowMessage(), заставляющий клиента вывести в консоль параметр, заданный сервером. Хостингом службы
WCF является консольное приложение. Все клиенты разделяют между собой один и тот же сервис. Если вкратце, то
ServiceBehavior.InstanceContextMode = InstanceContextMode.Single,
ServiceContract.SessionMode = SessionMode.Allowed, привязка -
WSDualHttpBinding. Служба запускается и вроде работает нормально, а вот клиент при вызове методf Register() блокируется и после некоторого времени ожидания выбрасывает
EndPointNotFoundException: Прослушивание на localhost:8733/Design_Time_Addresses/WCFDuplexServ... не выполняла ни одна конечная точка, которая могла бы принять сообщение. В чем ошибка?
Контракты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>