Фактическое поведение правильное.Вы использовали связующий элемент CompositeDuplex - значение составного слова - именно то, что вы получаете - два отдельных канала, каждый из которых работает в одном направлении.Композитный дуплекс необходим только для транспортного канала, который по умолчанию не поддерживает дуплексную связь.Это не относится к транспортному каналу TCP - проверьте примечания .Если вы не используете CompositeDuplex, он должен работать так, как вы ожидали.Также нет необходимости определять совершенно новую пользовательскую привязку, чтобы разрешить потоковую передачу. NetTcpBinding также имеет свойство TransportMode, которое можно указать в конфигурации.
РЕДАКТИРОВАТЬ: Я подготовил рабочий пример с дуплексной связью Net.TCP.Это не использует потоковую передачу.Вы правы, что потоковая передача невозможна при использовании дуплексной связи по протоколу TCP.Вы можете попытаться объединить дуплексную связь с каналом чанкинга или проверить Расширения WCF (коммерческий продукт).
Общие контракты
namespace NetTcpDuplexContracts
{
[ServiceContract(SessionMode = SessionMode.Required,
CallbackContract = typeof(IDuplexServiceCallback))]
public interface IDuplexService
{
[OperationContract(IsOneWay = true)]
void DoAction(string message);
}
public interface IDuplexServiceCallback
{
[OperationContract(IsOneWay = true)]
void ConfirmAction(string message);
}
}
Сервис и хост
namespace NetTcpDuplexService
{
public class DuplexService : IDuplexService
{
public void DoAction(string message)
{
Console.WriteLine("DoAction: " + message);
var callbackChannel =
OperationContext.Current.GetCallbackChannel<IDuplexServiceCallback>();
callbackChannel.ConfirmAction("Ping back " + message);
}
}
class Program
{
public static void Main(string[] args)
{
try
{
using (var host = new ServiceHost(typeof(DuplexService)))
{
host.Open();
Console.ReadLine();
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.ReadLine();
}
}
}
}
Конфигурация сервиса
<configuration>
<system.serviceModel>
<services>
<service name="NetTcpDuplexService.DuplexService">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8800/NetTcpDuplexService"/>
</baseAddresses>
</host>
<endpoint address="" binding="netTcpBinding" contract="NetTcpDuplexContracts.IDuplexService" />
</service>
</services>
</system.serviceModel>
</configuration>
Обратный звонок и клиент
namespace NetTcpDuplexClient
{
public class DuplexServiceCallback : IDuplexServiceCallback
{
public void ConfirmAction(string message)
{
Console.WriteLine(message);
}
}
class Program
{
public static void Main(string[] args)
{
DuplexChannelFactory<IDuplexService> factory = null;
try
{
var callbackService = new DuplexServiceCallback();
var context = new InstanceContext(callbackService);
factory = new DuplexChannelFactory<IDuplexService>(context, "IDuplexService_NetTcp");
var channel = factory.CreateChannel();
channel.DoAction("Hello world");
factory.Close();
Console.ReadLine();
}
catch (Exception e)
{
if (factory != null && factory.State != CommunicationState.Closed)
{
factory.Abort();
}
Console.WriteLine(e.Message);
Console.ReadLine();
}
}
}
}
Клиентская конфигурация
<configuration>
<system.serviceModel>
<client>
<endpoint name="IDuplexService_NetTcp" address="net.tcp://localhost:8800/NetTcpDuplexService" binding="netTcpBinding"
contract="NetTcpDuplexContracts.IDuplexService" />
</client>
</system.serviceModel>
</configuration>