2009-05-14 3 views
81

Coloro RFC "fine" mandato da ogni RFC-client che si guardano di non utilizzare più di 2 connessioni per host ...Come posso programmazione rimuovere il limite di 2 connessione in WebClient

Microsoft ha implementato questo in WebClient. So che può essere disattivato con

App.config:

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

(trovato su http://social.msdn.microsoft.com/forums/en-US/netfxnetcom/thread/1f863f20-09f9-49a5-8eee-17a89b591007)

Ma come posso fare a livello di codice?

Secondo l a http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit.aspx

"La modifica della proprietà DefaultConnectionLimit non ha alcun effetto sulla oggetti ServicePoint esistente; colpisce solo gli oggetti ServicePoint che sono inizializzato dopo la modifica Se il valore di questa proprietà non è stata set. direttamente o tramite la configurazione, il valore predefinito è costante DefaultPersistentConnectionLimit. "

Mi piacerebbe meglio configurare il limite quando installo il WebClient, ma rimuovere semplicemente questa triste limitazione programmaticamente all'inizio del mio programma andrebbe bene.

Il server accede non è un webserver regolare in internet, ma sotto il mio controllo e nella LAN locale. Voglio fare chiamate API, ma non uso servizi web o servizi remoti

+0

Potrei passare questa domanda se sapessi perché è necessario violare gli standard internazionali. –

+15

Non è davvero uno standard. RFC "raccomanda" di limitare i client a due connessioni, ma non è davvero un requisito. Più che probabile, il poster deve scaricare più di 2 elementi contemporaneamente. –

+12

Accedo a un'API sul mio server. Non voglio fare del male a host in internet. – Christian

risposta

48

Con alcuni suggerimenti da qui e altrove sono riuscito a risolvere il problema nella mia applicazione sovrascrivendo la classe WebClient usavo:

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

IMHO che l'impostazione di 'System.Net.ServicePointManager.DefaultConnectionLimit' è una soluzione migliore, in quanto non si può presumere che' WebRequest' sia un ' HttpWebRequest', ad esempio, potrebbe essere un 'FileRequest'. – Dennis

5

Se si trova l'oggetto ServicePoint utilizzato dal proprio client Web, è possibile modificare il limite di connessione. Gli oggetti HttpWebRequest dispongono di un accesso per recuperare quello che sono stati costruiti per essere utilizzati, in modo da poterlo fare in questo modo. Se sei fortunato, tutte le tue richieste potrebbero finire per condividere lo stesso ServicePoint in modo da doverlo fare solo una volta.

io non conosco alcun modo globale per modificare il limite. Se hai modificato DefaultConnectionLimit abbastanza presto nell'esecuzione, probabilmente starai bene.

In alternativa, si può solo vivere con il limite di connessione, dal momento che la maggior parte del software server sta per strozzare comunque. :)

+0

Questo server non mi strozzerà (di fatto, lo farà, ma in un modo diverso) poiché è completamente sotto il mio controllo – Christian

+1

Un server potrebbe rallentare con molte connessioni, ma non l'ho mai provato anche con un piccolo server (ospitato in una VM limitata). Il limite 2 sul lato client mi ha trattenuto dall'altra parte. L'aumento del limite ha liberato la situazione. –

+1

Dubito anche che nessuno dei browser di oggi obbedisca al limite di HTTP 1.1 RFC di 2. –

4

Abbiamo una situazione per quanto riguarda il pezzo di sopra di configurazione in App. config

Affinché questo sia valido in un'applicazione di console, abbiamo aggiunto la dll di riferimento System.Configuration. Senza il riferimento, quanto sopra era inutile.

110

per chi fosse interessato:

System.Net.ServicePointManager.DefaultConnectionLimit = x (dove x è il numero desiderato di connessioni)

senza bisogno di riferimenti aggiuntivi

solo assicurarsi che questo viene chiamato prima della creazione del punto di servizio come detto sopra nel post.

+0

Quindi questo potrebbe essere aggiunto a application_start nel globale? quindi influisce su tutte le connessioni fatte? – TheAlbear

+0

Come & dove aggiungere System.Net.ServicePointManager.DefaultConnectionLimit = x? –

+0

Stranamente, il commento di codice per DefaultConnectionLimit (navigazione usando F12) dice che il suo valore predefinito è Int32.MaxValue. Tuttavia con l'ispezione di debug è 2 come richiesto. – crokusek

6

Questa soluzione consente di modificare il limite di connessione in qualsiasi momento:

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

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

La prima volta che qualcuno chiama questo FindServicePoint, viene creata un'istanza ServicePoint e WeakReference è creato per tenere su di esso all'interno il ServicePointManager. Le richieste successive al gestore per lo stesso URI restituiscono la stessa istanza. Se la connessione non viene utilizzata dopo, il GC lo pulisce.

+1

L'unico problema con FindServicePoint è che ti restituisce un ServicePoint ma non sai se sarà lo stesso ServicePoint ricevuto dal cliente. – jeffa00

+2

Questo non è un "problema", è solo una parte normale del lavoro. Come con tutte le soluzioni, devi trovare un modo per testarlo. Il mio modo era di impostare le impostazioni in .config su "1", osservare le prestazioni terribili e impostarle in codice (come qui), osservando le prestazioni migliorate. – Abacus

+0

Il 'ServicePoint' viene perso (insieme alle impostazioni) dopo' MaxIdleTime' –

Problemi correlati