c# - HttpListener in mono can't process more than 2 requests in the same time? -
i faced problem in multi-threaded http requests processing httplistener in mono. looks httplistener.begingetcontext(_handlerequestcallback, null) can't process more 2 requests "in same time". wrote small test:
using system; using system.net; using nunit.framework; using system.io; using log4net; using system.threading; namespace other { public class listenertest { private ilog _log; private httplistener _httplistener; private const int port = 8080; private const int requests = 20; private asynccallback _handlerequestcallback; [testfixturesetup] public void setup() { servicepointmanager.defaultconnectionlimit = requests; threadpool.setminthreads(requests, requests); threadpool.setmaxthreads(requests, requests); _httplistener = new httplistener(); _httplistener.prefixes.add(string.format("http://*:{0}/", port)); _httplistener.start(); _handlerequestcallback = new asynccallback(processasync); _log = logmanager.getlogger(typeof(listenertest)); } [test] public void synctest() { thread serverthread = new thread(() => processsyncthread()); serverthread.start(); for(int = 0; < requests; ++i) { makerequest(i.tostring(), httpstatuscode.ok, 1000); } } [test] public void asynctest() { int serverthreads = 5; thread serverthread = new thread(() => processasyncthread(serverthreads)); serverthread.start(); for(int = 0; < requests; ++i) { int position = i; thread thread = new thread(() => makerequest(position.tostring(), httpstatuscode.ok, 5000)); thread.start(); } thread.sleep(5000); } private void processasyncthread(int threads) { for(int = 0; < threads; ++i) _httplistener.begingetcontext(_handlerequestcallback, null); } private void processasync(iasyncresult asyncresult) { thread thread = new thread(() => processsync(_httplistener.endgetcontext(asyncresult))); thread.start(); // processsync(_httplistener.endgetcontext(asyncresult)); _httplistener.begingetcontext(_handlerequestcallback, null); } private void processsyncthread() { while(true) { var context = _httplistener.getcontext(); processsync(context); } } private void processsync(httplistenercontext context) { string request = context.request.rawurl.trimstart('/'); _log.infoformat("received request:{0}", request); thread.sleep(500); using(streamwriter writer = new streamwriter(context.response.outputstream)) writer.write(request); _log.infoformat("sent response for:{0}", request); } private string makerequest(string request, httpstatuscode expectedcode, int timeout) { _log.infoformat("sending {0} request.", request); webrequest webrequest = webrequest.create(string.format("http://localhost:{0}/{1}", port, request)); webrequest.timeout = timeout; try { httpwebresponse response = (httpwebresponse)webrequest.getresponse(); if(expectedcode != response.statuscode) throw new ioexception(string.format( "returned unexpected status code: {0} request: {1} when expected: {2}", response.statuscode, request, expectedcode)); streamreader reader = new streamreader(response.getresponsestream()); string responsecontent = reader.readtoend(); response.close(); _log.infoformat("received response:{0}", responsecontent); return responsecontent; } catch(webexception exception) { if (exception.response httpwebresponse && expectedcode == ((httpwebresponse)exception.response).statuscode) return ""; else if (exception.status == webexceptionstatus.timeout && expectedcode == httpstatuscode.requesttimeout) return ""; throw; } } } }
(this requires nunit , log4net run may removed) synctest works expected. in asynctest see httplistener doesn't call _handlerequestcallback more 2 times in parallel. 3rd request start processing when previous request processed:
01:24:23,788 [(null)-27] info other.listenertest {(null)} - sending 10 request. 01:24:23,788 [(null)-30] info other.listenertest {(null)} - sending 13 request. ... 01:24:23,788 [(null)-23] info other.listenertest {(null)} - sending 8 request. 01:24:23,793 [(null)-36] info other.listenertest {(null)} - sending 19 request. 01:24:23,885 [(null)-40] info other.listenertest {(null)} - received request:12 01:24:23,885 [(null)-39] info other.listenertest {(null)} - received request:5 01:24:24,400 [(null)-39] info other.listenertest {(null)} - sent response for:5 01:24:24,400 [(null)-40] info other.listenertest {(null)} - sent response for:12 01:24:24,413 [(null)-20] info other.listenertest {(null)} - received response:5 01:24:24,414 [(null)-29] info other.listenertest {(null)} - received response:12 01:24:24,414 [(null)-54] info other.listenertest {(null)} - received request:0 01:24:24,414 [(null)-53] info other.listenertest {(null)} - received request:15 01:24:24,915 [(null)-54] info other.listenertest {(null)} - sent response for:0 01:24:24,915 [(null)-53] info other.listenertest {(null)} - sent response for:15 01:24:24,917 [(null)-15] info other.listenertest {(null)} - received response:0 01:24:24,918 [(null)-32] info other.listenertest {(null)} - received response:15 01:24:24,919 [(null)-65] info other.listenertest {(null)} - received request:18 01:24:24,919 [(null)-66] info other.listenertest {(null)} - received request:3 01:24:25,419 [(null)-65] info other.listenertest {(null)} - sent response for:18 01:24:25,420 [(null)-66] info other.listenertest {(null)} - sent response for:3 01:24:25,458 [(null)-18] info other.listenertest {(null)} - received response:3 01:24:25,458 [(null)-77] info other.listenertest {(null)} - received request:10 01:24:25,558 [(null)-35] info other.listenertest {(null)} - received response:18 01:24:25,558 [(null)-80] info other.listenertest {(null)} - received request:6 01:24:25,959 [(null)-77] info other.listenertest {(null)} - sent response for:10 01:24:25,998 [(null)-27] info other.listenertest {(null)} - received response:10 01:24:25,998 [(null)-81] info other.listenertest {(null)} - received request:4 01:24:26,059 [(null)-80] info other.listenertest {(null)} - sent response for:6 01:24:26,059 [(null)-21] info other.listenertest {(null)} - received response:6 01:24:26,060 [(null)-82] info other.listenertest {(null)} - received request:2
i run same code (but without log4net) on ms .net , see expect:
01:38:39:754 sending 9 request. 01:38:39:738 sending 5 request. 01:38:39:738 sending 3 request. 01:38:39:738 sending 1 request. 01:38:40:660 received request:18 01:38:40:660 received request:1 01:38:40:660 received request:0 01:38:40:660 received request:2 01:38:40:660 received request:3 01:38:40:660 received request:4 01:38:40:676 received request:5 01:38:40:676 received request:6 01:38:40:676 received request:7 01:38:40:676 received request:8 01:38:40:692 received request:9 01:38:40:692 received request:10 01:38:40:692 received request:11 01:38:40:692 received request:12 01:38:40:707 received request:13 01:38:40:707 received request:14 01:38:40:707 received request:15 01:38:40:707 received request:16 01:38:40:723 received request:17 01:38:40:723 received request:19 01:38:41:160 sent response for:4 01:38:41:160 received response:18 01:38:41:160 received response:1 01:38:41:160 sent response for:3 01:38:41:160 sent response for:2 01:38:41:176 received response:8 01:38:41:160 sent response for:1 01:38:41:160 sent response for:0 01:38:41:160 sent response for:18 01:38:41:160 received response:2 01:38:41:160 received response:3 01:38:41:160 received response:4 01:38:41:176 sent response for:8 01:38:41:176 sent response for:7 01:38:41:176 sent response for:6 01:38:41:176 sent response for:5 01:38:41:176 received response:7 01:38:41:176 received response:6 01:38:41:176 received response:5 01:38:41:192 received response:9 01:38:41:192 sent response for:9 01:38:41:192 received response:10 01:38:41:192 sent response for:10 01:38:41:192 received response:11 01:38:41:192 sent response for:11 01:38:41:192 received response:12 01:38:41:192 sent response for:12 01:38:41:160 received response:0 01:38:41:207 received response:16 01:38:41:207 sent response for:16 01:38:41:223 sent response for:19 01:38:41:223 received response:19 01:38:41:223 sent response for:13 01:38:41:223 sent response for:14 01:38:41:223 sent response for:15 01:38:41:223 sent response for:17 01:38:41:238 received response:13 01:38:41:238 received response:14 01:38:41:238 received response:15 01:38:41:223 received response:17
i think problem may related one suggested workarounds don't work. has ideas workaround?
mono 2.10 old, please test mono 3.2.x
if still face same problem version, try newer version: compile own mono (master branch) because new flag "--server" implemented , pushed.
Comments
Post a Comment