/// <summary> /// Expect incoming messages from non-Auto-Run mode service and system exceptions /// </summary> /// <param name="duration"></param> /// <param name="all"></param> /// <returns></returns> public int ExpectMessages(TimeSpan duration, ref List <ManagedEvent> all) { lock (staLock) { if (all == null) { throw new Exception("must not input a null list"); } int maxSleep; maxSleep = (int)duration.TotalMilliseconds;// 1000 * (duration.Minutes * 60 + duration.Seconds); // use a queue type here since List<> sometimes will break the order of item inside Queue <ManagedEvent> q = new Queue <ManagedEvent>(); int actualSleep = 0; while (actualSleep < maxSleep) { actualSleep += 20; System.Threading.Thread.Sleep(20); lock (eventPipe) { if (eventPipe.Count > 0) { while (eventPipe.Count > 0) { ManagedEvent e = eventPipe.Dequeue(); q.Enqueue(e); } break; } } } all = q.ToList <ManagedEvent>(); return(all.Count); } }
/// <summary> /// Tcp Client thread /// </summary> /// <param name="o"></param> private void ReceiveLoop(object o) { ManagedStream ms = o as ManagedStream; TimeSpan idleTime = TimeSpan.FromMilliseconds(0); TimeSpan sleepTime = TimeSpan.FromMilliseconds(200); Stream s; HttpEndpointBase usedEndpoint = null; TcpClient c = ms.LocalTcpClient; // id it's using SSL, must authenticate self as server firstly if (ms.PortInfo.IsSSL) { SslStream ssl = new SslStream(c.GetStream(), true); try { ssl.AuthenticateAsServer(ms.PortInfo.ServerCertificate, false, System.Security.Authentication.SslProtocols.Tls, false); } catch (Exception e) { lock (eventPipe) { ManagedEvent exp = new ManagedEvent(); exp.EventType = EventType.Exception; exp.Exception = e; eventPipe.Enqueue(exp); return; } } s = ssl; } else { s = c.GetStream(); } ms.LocalStream = s; using (s) { while (this.running && idleTime < this.idleTimeout) { // if no data available, wait for a while if (c.Available == 0) { Thread.Sleep(sleepTime); idleTime += sleepTime; } // if data coming else { idleTime = TimeSpan.FromMilliseconds(0); byte[] data; // receive data using (var t = new MemoryStream()) { var buf = new byte[c.ReceiveBufferSize]; lock (ms) { do { var bytes = s.Read(buf, 0, buf.Length); t.Write(buf, 0, bytes); } while (c.Available > 0); ms.LastUsed = DateTime.Now; } data = t.ToArray(); } // pack as ManagedEvent var e = new ManagedEvent(); e.Data = data; e.Sender = c.Client.RemoteEndPoint as IPEndPoint; e.EventType = EventType.IncomingRequest; //parse the endpoint string str = Encoding.UTF8.GetString(data); e.Text = str; // try to parse as http try { HttpRequest req = new HttpRequest(); req.Parse(e.Text); e.ParsedHttpRequest = req; } catch { } if (usedEndpoint == null) { if (e.ParsedHttpRequest == null) { //first message is not http e.EventType = EventType.Exception; e.Exception = new Exception("The 1st request from this context is not an HTTP Request"); } else { lock (m_endpoints) { if (m_endpoints.ContainsKey(ms.PortInfo.Port)) { List <HttpEndpointBase> hebs = m_endpoints[ms.PortInfo.Port]; // find specific endpoint var q = from r in hebs where ( from u in r.Urls where e.ParsedHttpRequest.RequestUrl.Path.ToLower().Contains(u.ToLower()) select u ).Count() > 0 select r; // if found if (q.Any()) { e.ServiceEndpoint = (HttpEndpointBase)q.First(); usedEndpoint = e.ServiceEndpoint; } } } } } else { e.ServiceEndpoint = usedEndpoint; } // if service is auto-run, dispatch to its own pipe if (e.ServiceEndpoint != null && e.ServiceEndpoint.AutoRun) { lock (e.ServiceEndpoint.eventPipe) { e.ServiceEndpoint.eventPipe.Enqueue(e); } } else { lock (eventPipe) { eventPipe.Enqueue(e); } } } } } }