Як я можу програмно видалити обмеження на 2 підключення в WebClient


88

Ті "чудові" RFC вимагають від кожного RFC-клієнта, щоб вони остерігались не використовувати більше 2 з'єднань на хост ...

Microsoft впровадила це в WebClient. Я знаю, що це можна вимкнути за допомогою

App.config:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
 <system.net> 
  <connectionManagement> 
   <add address="*" maxconnection="100" /> 
  </connectionManagement> 
 </system.net> 
</configuration> 

(знайдено на http://social.msdn.microsoft.com/forums/en-US/netfxnetcom/thread/1f863f20-09f9-49a5-8eee-17a89b591007 )

Але як я можу це зробити програмно?

Відповідно до http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit.aspx

"Зміна властивості DefaultConnectionLimit не впливає на існуючі об'єкти ServicePoint; воно впливає лише на об'єкти ServicePoint, які ініціалізуються після зміни. Якщо значення цієї властивості не було встановлено ні безпосередньо, ні через конфігурацію, значенням за замовчуванням є константа DefaultPersistentConnectionLimit."

Я хотів би найкраще налаштувати ліміт, коли я запускаю WebClient, але просто програмне видалення цього сумного обмеження на початку моєї програми також було б непоганим.

Сервер, до якого я отримую доступ, не є звичайним веб-сервером в Інтернеті, а знаходиться під моїм контролем та в локальній мережі. Я хочу робити API-дзвінки, але я не використовую веб-сервіси та віддалене керування


15
Це насправді не стандарт. RFC "рекомендує" обмежити клієнтів двома з'єднаннями, але насправді це не є вимогою. Швидше за все, плакат повинен завантажувати більше 2 елементів одночасно.
Ерік Функенбуш

12
Я отримую доступ до API на власному сервері. Я не хочу нашкодити хостам в Інтернеті.
Крістіан

12
Я збільшив ліміт підключення для створення інструменту для перевірки навантаження. Насправді важко завантажити тест з двома з'єднаннями. Я впевнений, що є багато причин, що не переглядають веб-сторінки, щоб використовувати багато зв’язків.
ScottS

1
До речі, наведена вище конфігурація вплине на всі контрольовані підключення .Net, а не лише на веб-клієнта.
ScottS

2
Чому більше двох? Звернемося до питання: чому я не міг асинхронно одночасно подати на сервер більше двох запитів? 2 - це буквально обмеження.
Csaba Toth

Відповіді:


50

За допомогою кількох порад звідси та в інших місцях мені вдалося виправити це у своєму додатку, замінивши клас WebClient, який я використовував:

class AwesomeWebClient : WebClient {
    protected override WebRequest GetWebRequest(Uri address) {
        HttpWebRequest req = (HttpWebRequest)base.GetWebRequest(address);
        req.ServicePoint.ConnectionLimit = 10;
        return (WebRequest)req;
    }
}

28
ІМХО, що встановлення параметра System.Net.ServicePointManager.DefaultConnectionLimitє кращим рішенням, оскільки не може припустити, що значення WebRequesta є HttpWebRequest, наприклад, це може бути a FileRequest.
Денніс

120

для зацікавлених:

System.Net.ServicePointManager.DefaultConnectionLimit = x (де x - бажана кількість з'єднань)

немає необхідності в додаткових посиланнях

просто переконайтеся, що це називається ДО створення точки обслуговування, як зазначено вище у дописі.


То чи можна це додати до application_start у глобальному? так це впливає на всі встановлені зв’язки?
TheAlbear

Як і де додати System.Net.ServicePointManager.DefaultConnectionLimit = x?
Арул Сідтан

Як не дивно, але коментар коду для DefaultConnectionLimit (навігація за допомогою F12) говорить, що за замовчуванням це Int32.MaxValue. Однак за результатами перевірки налагодження це 2, як заявлено.
crokusek

7

Це рішення дозволяє змінити обмеження підключення в будь-який час :

private static void ConfigureServicePoint(Uri uri)
{
    var servicePoint = ServicePointManager.FindServicePoint(uri);

    // Increase the number of TCP connections from the default (2)
    servicePoint.ConnectionLimit = 40;
}

Перший раз, коли хтось викликає цей FindServicePoint , створюється екземпляр ServicePoint і створюється WeakReference , щоб утримувати його всередині ServicePointManager . Подальші запити до менеджера за тим самим Uri повертають той самий екземпляр. Якщо з'єднання не використовується після, GC очищає його.


1
Єдина проблема FindServicePoint полягає в тому, що він передає вам один ServicePoint, але ви не знаєте, чи буде це той самий ServicePoint, який отримує ваш клієнт.
jeffa00

2
Це не "проблема", це просто нормальна частина роботи. Як і у всіх рішеннях, вам потрібно знайти спосіб перевірити це. Моїм способом було встановити параметр у .config на "1", спостерігати за жахливою продуктивністю та встановлювати його в коді (як тут), спостерігаючи за покращеною продуктивністю.
Abacus

1
ServicePointВтрачається (разом з вашими настройками) післяMaxIdleTime
Colin Breame

5

Якщо ви виявите, що об’єкт ServicePoint використовується веб-клієнтом, ви можете змінити обмеження його підключення. Об'єкти HttpWebRequest мають доступ для отримання того, для якого вони були сконструйовані, щоб ви могли зробити це таким чином. Якщо вам пощастить, усі ваші запити можуть у підсумку використовувати один і той же ServicePoint, тож вам доведеться це зробити лише один раз.

Я не знаю жодного глобального способу змінити межу. Якщо ви змінили DefaultConnectionLimit досить рано під час виконання, напевно, у вас все буде добре.

Крім того, ви можете просто жити з обмеженням підключення, оскільки більшість серверного програмного забезпечення все одно вас задушить. :)


Цей сервер мене не задушить (насправді, буде, але по-іншому), оскільки він повністю під моїм контролем
Крістіан

1
Сервер може загрожувати великою кількістю з'єднань, але я не відчував цього навіть з невеликим сервером (розміщений в обмеженій віртуальній машині). Ліміт 2 на стороні клієнта стримував мене з іншого боку. Збільшення ліміту звільнило ситуацію.
Csaba Toth

1
Я також сумніваюся , що будь-який з сьогоднішнього браузера буде підкорятися ліміту HTTP 1.1 RFC про 2.
Чаба Toth

4

У нас ситуація щодо вищезазначеної частини конфігурації в App.Config

Для того, щоб це було дійсним у програмі CONSOLE, ми додали посилання dll на System.Configuration. Без посилання вищезазначене було марним.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.