Могу ли я что-нибудь сделать, чтобы X509 работал лучше иследовал передовой практике нового канала для каждого запроса, или это медленное согласование является неотъемлемым недостатком использования X509? для безопасности WCF?
Для tl;dr перейдите к Обновление 3в конце для источника этого.
Лучшей практикой для каналов WCF является «повторное использование ChannelFactory, но создание нового канала для каждого запроса», и я всегда поступал так. Например. Производительность одного канала WCF по сравнению с несколькими каналами
В настоящее время я экспериментирую с использованием сертификатов X509 в качестве учетных данных безопасности, и CreateChannel каждый раз занимает много времени (15 секунд+). Повторное использование канала впоследствии дает хорошую производительность (если я правильно понимаю, потому что симметричные ключи используются после первоначальной аутентификации с открытым/закрытым ключом, которая происходит при вызове CreateChannel), но это плохая практика.
На стороне сервера:
var managerCertificate = new X509Certificate2(@"Manager.pfx", "");
var host = new ServiceHost(typeof(ManagerService));
host.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
host.Credentials.ClientCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;
host.Credentials.ServiceCertificate.Certificate = managerCertificate;
host.Open();
Console.ReadLine();
На стороне исполнителя (медленно выполнять каждый запрос):
var workerCertificate = new X509Certificate2(@"Worker.pfx", "");
var cfact = new ChannelFactory("client");
cfact.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
cfact.Credentials.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;
cfact.Credentials.ClientCertificate.Certificate = workerCertificate;
for (int i = 0; i < 10; i++)
{
using (IManagerService channel = cfact.CreateChannel()
{
Console.WriteLine(channel.GetMyData("test data" + i));
}
}
И если я перенесу вызов CreateChannel за пределы цикла for для его повторного использования, только первый запрос займет существенное время.
Кроме того, я использую NetTcpBinding.
Обновление 1:Краткая выборка результатов:
0: 546.875ms
1: 281.25ms
2: 281.25ms
3: 17484.375ms
4: 250ms
5: 234.375ms
6: 250ms
7: 250ms
8: 265.625ms
9: 250ms
250 мс — это не слишком ужасные накладные расходы на вызов (хотя и огромные по сравнению с повторным использованием канала), 17 секунд), которые различаются по частоте, иногда 1 к 3. Если сервер остается в рабочем состоянии между запусками клиентского исполняемого файла, то первоначальная стоимость согласования исчезает при последующих запусках, так что это хорошо.
Обновление 2:Предположительно, это не связано с брандмауэром/антивирусом, так как я попробовал это внутри виртуальной машины со стандартной XP и отключенным брандмауэром и получил крайне противоречивые результаты. Один раз предсказуемо (400мс за звонок), другой эти сумасшедшие паузы.
Обновление 3:После просмотра журналов трассировки выяснилось, что при создании нового канала каждый раз требуется много времени (и активность, которая является причиной периодической паузы):
0
3
0
255
MYCOMPUTER
в журнале также говорится: Название связанной активности: Действие процесса «http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue».
Итак, если у кого-то есть какие-либо идеи о том, почему это может постоянно приостанавливаться на 17,5 секунд и всегда ли это будет стоить 250 мс в обычном режиме, тогда вы будете отвечать на мой вопрос!