[.NET] HttpListener geeft niet volledige response

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • armageddon_2k1
  • Registratie: September 2001
  • Laatst online: 27-07 10:18
Ik heb een HttpListener service draaien geschreven in .NET. Deze service verbindt met een API van een CRM systeem en geeft JSON-data terug van gegevens uit dat systeem. Het werkt allemaal naar behoren op de lokale machine, maar als ik via een computer in het netwerk deze service benader, dan komt het af en toe voor dat ie niet de volledige response terug geeft. Dit is voornamelijk het geval bij een een flink grote respons (van +/- 500kb).

Als ik dan nogmaals de gegevens opvraag krijg ik het resterende gedeelte + een deel van de response van mijn nieuwe request.

Mijn eerste idee was dat het te maken had met de manier waarop ik de thread voor het verwerken van een request deed. Die was niet zo heel netjes, nl. als volgt: http://bartdesmet.net/blo...tp-request-reflector.aspx

Ik dacht eerst dat het te maken had met de buffer van het HttpListenerResponse object, maar deze verstuurt als het goed is pas nadat je Close() hebt aangeroepen. Vervolgens heb ik geprobeerd of ie automatisch op SendChunked stond, maar dat was ook niet het geval.

Heeft iemand een idee waarom de browser een deel ontvangt en dan denk dat het al klaar is?

Mijn request worden als volgt verwerkt:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        public void Start()
        {
            listener.Start();
            processor = new RequestProcessor(); // mijn processor class
            processor.Start();
            log.Info(String.Format("Server ready and listening at http://{0}:{1}/", System.Configuration.ConfigurationManager.AppSettings["ListenAdress"], System.Configuration.ConfigurationManager.AppSettings["ListenIp"]));
            listener.BeginGetContext(ListenerCallback, listener);
        }

        private void ListenerCallback(IAsyncResult result)
        {
            HttpListener l = (HttpListener)result.AsyncState;
            HttpListenerContext context = l.EndGetContext(result);
            processor.ProcessRequest(context);

            // de volgende regel wordt uitgevoerd om klaar te staan voor de volgende request. Dit houdt vooralsnog in dat er maar 1 request per keer kan zijn, maar dat is geen probleem. Ik heb dit gedaan om het wat simpeler te houden
            listener.BeginGetContext(ListenerCallback, listener);
        }


Waarna mijn processor het volgende doet:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
        public void ProcessRequest(System.Net.HttpListenerContext context)
        {
          // ophalen data uit CRM systeem, omzetten naar JSON
          byte[] buffer = System.Text.Encoding.UTF8.GetBytes(data);            
          context.Response.ContentEncoding = System.Text.Encoding.UTF8;
          context.Response.Headers.Add("Content-Type","application/json;charset=UTF-8");
          context.Response.Headers.Add(System.Net.HttpResponseHeader.CacheControl, "no-cache");
          context.Response.SendChunked = false;
          context.Response.ContentLength64 = buffer.Length;
          context.Response.OutputStream.Write(buffer, 0, buffer.Length);
          context.Response.OutputStream.Close();
          context.Response.Close();
        }

Engineering is like Tetris. Succes disappears and errors accumulate.


Acties:
  • 0 Henk 'm!

  • armageddon_2k1
  • Registratie: September 2001
  • Laatst online: 27-07 10:18
Grmbl... zit je je er een hele avond op stuk te bijten, blijkt het helemaal niet door mijn applicatie te komen, maar door een Firefox plugin JSONView. Deze gaat namelijk niet heel erg goed om met grotere bestanden, waardoor ie de request afkapt.

Als ik hem gewoon kaal in de browser opvraag, dan zie ik hem inderdaad langzaam de output geven. Hoe krijg ik het voor elkaar dat de content pas getoond wordt als ie volledig binnen is?

Engineering is like Tetris. Succes disappears and errors accumulate.


Acties:
  • 0 Henk 'm!

  • Radiant
  • Registratie: Juli 2003
  • Niet online

Radiant

Certified MS Bob Administrator

Content eerst intern opbouwen in een buffertje en dan in één keer versturen?

Acties:
  • 0 Henk 'm!

  • armageddon_2k1
  • Registratie: September 2001
  • Laatst online: 27-07 10:18
Maar dat doe ik nu toch? Ik bouw de buffer op en verstuur hem in 1x?

Engineering is like Tetris. Succes disappears and errors accumulate.


Acties:
  • 0 Henk 'm!

  • D-Raven
  • Registratie: November 2001
  • Laatst online: 10-09 20:32
Je code ziet er an sich goed uit.
Heb je niet gewoon het probleem dat de browser alvast de content gaat tonen terwijl het binnenkomt omdat het downloaden van die 500kb even duurt?

Acties:
  • 0 Henk 'm!

  • armageddon_2k1
  • Registratie: September 2001
  • Laatst online: 27-07 10:18
Ja, daar lijkt het wel op.
Als ik Content-Type op text/plain zet, dan gaat het helemaal goed, alleen vind ik dit erg raar gedrag.

Als ik een PHP-script maak welke 1MB aan JSON data over moet gooien heb ik dit soort problemen niet.

Engineering is like Tetris. Succes disappears and errors accumulate.


Acties:
  • 0 Henk 'm!

  • Vedett.
  • Registratie: November 2005
  • Laatst online: 26-09 16:17
1) Ik weet niet wat voor stream dat is, en of AutoFlush daar op true staat. Maar misschien moet je een .Flush oproepen op de stream voor je hem sluit.
2) Ik denk dat WCF beter geschikt is voor wat je wilt bereiken.

Acties:
  • 0 Henk 'm!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 22:59

alienfruit

the alien you never expected

Wat geeft Charles of een andere HTTP Proxy aan? Ik heb vergelijkbare code en tot heden werkt dat prima.

Acties:
  • 0 Henk 'm!

  • armageddon_2k1
  • Registratie: September 2001
  • Laatst online: 27-07 10:18
Met Charles heb ik ook even gekeken. Het probleem is dat het niet structureel is. Waarom dat is weet ik niet helemaal.

Ik heb het vermoeden dat het met het ophalen van favicon.ico te maken heeft. Maar ik kan nog niet helemaal plaatsen hoe het komt.

Heb wel de output iets aangepast:
C#:
1
2
3
4
5
6
7
8
9
            using (Stream s = context.Response.OutputStream)
            {                
                using (StreamWriter writer = new StreamWriter(s))
                {
                    writer.AutoFlush = false;
                    writer.Write(data);
                }
            }
            context.Response.Close();


Ik heb het probleem overigens niet meer.

[ Voor 3% gewijzigd door armageddon_2k1 op 09-03-2011 17:21 ]

Engineering is like Tetris. Succes disappears and errors accumulate.

Pagina: 1