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:
Waarna mijn processor het volgende doet:
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.