Мой тест показывает, что .NET Remoting в 1,5 раза быстрее, чем WCF 4.

Чтобы определить, следует ли моему проекту перейти с удаленного взаимодействия .net на WCF, я извлек его сетевую коммуникационную часть и реализовал ее с помощью WCF. Я запускаю версию для удаленного взаимодействия и версию wcf и в итоге обнаружил, что удаленное взаимодействие выполняется быстрее, чем wcf в 1,5 раза, что сильно отличается от статья о msdn.

Конфигурация теста

WCF и .NET Remoting используют tcp-канал без шифрования, без файла app.config. Скомпилирован в режиме релиза, без оптимизации.

Операции

Вот что делает моя программа. диаграмма последовательности

Здесь вы можете скачать два решения.

WCF тест

Хост службы

    ServiceHost host = new ServiceHost(typeof(Server), new Uri(string.Format("net.tcp://{0}:{1}/{2}", args[0], args[1], args[2])));
    var binding = new NetTcpBinding();
    binding.MaxReceivedMessageSize = 614400;
    binding.ReaderQuotas.MaxArrayLength = 512000;//a max picture of 500KB
    binding.Security.Mode = SecurityMode.None;
    host.AddServiceEndpoint(typeof(IServer), binding, string.Empty);
    host.Open();

Сервер

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single
    //, IncludeExceptionDetailInFaults = true
    , ConcurrencyMode = ConcurrencyMode.Reentrant
    )]
public class Server : IServer
{
    public EntryRequirement GetEntryRequirement()
    {
        return new EntryRequirement(new[] { "fuck", "sex" }, false);
    }

    public void AddClient()
    {
        var client = OperationContext.Current.GetCallbackChannel<IServerCallback>();
        var p = client.Profile;
        var x = client.Password;
        System.Diagnostics.Debug.WriteLine(p);
        System.Diagnostics.Debug.WriteLine(x);
    }
}

Сторона клиента

    Player player = new Player();
    player.Password = "12423";
    player.Profile = new Contracts.PlayerProfile
                         {
                             Description = "I'm a man.",
                             HeadImage = imageData,
                             Name = "Loveright"
                         };


    var binding = new NetTcpBinding();
    binding.Security.Mode = SecurityMode.None;
    Stopwatch watch = new Stopwatch();
    watch.Start();
    for (int i = 0; i < 20; i++)
    {
        ServerProxy server = new ServerProxy(player, binding, 
            new EndpointAddress(string.Format("net.tcp://{0}:{1}/{2}", args[0], args[1], args[2])));
        server.GetEntryRequirement();
        server.AddClient();
    }

    watch.Stop();

HeadImage - это изображение размером 139 КБ.

Класс игрока

[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
class Player : IServerCallback
{
    public PlayerProfile Profile { get; set; }

    public string Password { get; set; }

    public void ClientCollectionChangedEventHandler(object sender, ControllersChangedEventArgs e)
    {

    }

    public void ClientUpdatedEventHandler(object sender, ClientUpdatedEventArgs e)
    {

    }
}

.NET Remoting test

Хозяин

    var serverProv = new BinaryServerFormatterSinkProvider();
    serverProv.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
    var clientProv = new BinaryClientFormatterSinkProvider();
    IDictionary props = new Hashtable();
    props["port"] = args[1];
    props["name"] = "tcp server";
    var channel = new TcpChannel(props, clientProv, serverProv);

    ChannelServices.RegisterChannel(channel, false);

    System.Runtime.Remoting.RemotingConfiguration.RegisterWellKnownServiceType(typeof(Server),
                                args[2], System.Runtime.Remoting.WellKnownObjectMode.Singleton);

Клиент

    var serverProv = new BinaryServerFormatterSinkProvider();
    serverProv.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
    var clientProv = new BinaryClientFormatterSinkProvider();
    IDictionary props = new Hashtable();
    props["name"] = "tcp client " + Guid.NewGuid();
    props["port"] = 0;

    var channel = new TcpChannel(props, clientProv, serverProv);
    ChannelServices.RegisterChannel(channel, false);

    FileStream stream = new FileStream(@"logotz6.png", FileMode.Open);
    byte[] imageData = new byte[stream.Length];
    stream.Read(imageData, 0, imageData.Length);
    stream.Close();
    Player player = new Player();
    player.Password = "12423";
    player.Profile = new PlayerProfile
    {
        Description = "I'm a man.",
        HeadImage = imageData,
        Name = "Loveright"
    };

    Stopwatch watch = new Stopwatch();
    watch.Start();
    for (int i = 0; i < 20; i++)
    {
        var serverProxy = (IServer)Activator.GetObject(typeof(IServer), string.Format("tcp://{0}:{1}/{2}", args[0], args[1], args[2]));
        serverProxy.GetEntryRequirement();
        serverProxy.AddClient(player);
    }
    watch.Stop();

Вы можете скачать два решения здесь.

Результат

введите описание изображения здесь

Так сделать тест где-нибудь несправедливо по отношению к WCF?


person Gqqnbig    schedule 10.02.2012    source источник
comment
Удаленное взаимодействие устарело. Это основная причина для включения вашего приложения в график повышения - msdn.microsoft.com/en-us/library/kwdt6w2k%28v=VS.100%29.aspx   -  person Chris Holwerda    schedule 15.07.2013
comment
Так или иначе. Удаленное взаимодействие выполняется быстро, и WCF имеет некоторые ограничения, которых нет в удаленном взаимодействии. Теперь одно из моих приложений использует удаленное взаимодействие.   -  person Gqqnbig    schedule 24.07.2013
comment
До тех пор, пока я не смогу выжать ту же производительность из WCF, я буду продолжать использовать .net Remoting в моем наборе инструментов.   -  person AnthonyVO    schedule 25.10.2014
comment
Это была отладка или выпуск релиза? В этом ответе сборка Release, похоже, решает проблему.   -  person Artemix    schedule 12.11.2014
comment
Скомпилирован в режиме выпуска   -  person Gqqnbig    schedule 13.11.2014


Ответы (1)


Должен ли он быть королем кодирования сообщений?

Вы использовали binaryMessageEncoding вместо textMessageEncoding или soapMessageEncoding?

Для этого вы можете создать настраиваемую привязку:

internal sealed class MyBinding : CustomBinding
{
    private static readonly BindingElementCollection elementCollection;

    static MyBinding()
    {
        MessageEncodingBindingElement encoding = new BinaryMessageEncodingBindingElement();

        TcpTransportBindingElement transport = new TcpTransportBindingElement();

        elementCollection = new BindingElementCollection();
        elementCollection.Add(encoding);
        elementCollection.Add(transport);
    }

    internal MyBinding(string bindingName, string bindingNamespace)
        : base()
    {
        base.Namespace = bindingNamespace;
        base.Name = bindingName;
    }

    public override BindingElementCollection CreateBindingElements()
    {
        return elementCollection;
    }
}
person Rom Eh    schedule 09.08.2013
comment
Где вы обнаружите, что я использую textMessageEncoding или soapMessageEncoding? - person Gqqnbig; 18.08.2013
comment
Вы можете создать настраиваемую привязку (путем расширения класса CustomBinding (System.ServiceModel.Channels)). - person Rom Eh; 29.08.2013