// // Reader thread function for this endpoint/dispatcher. // Reads in blocking mode. // private void Reader() { MessageHeader mhdr; while (true) { try { // read/wait for an incoming message mhdr = _r.ReadMessageHeader(); } catch (System.IO.EndOfStreamException) { // the stream got closed, so we're going to shut down. // FIXME -- what does "shut down" entail? How do // I destroy everything that's involved with this // thread's handler? return; } // If this connection hasn't been validated, then we expect // a validate -- but only if the endpoint has a notion // of a connection (see constructor) if (!_valid) { if (mhdr.messageType != MessageType.ValidateConnection) { throw new InvalidOperationException("Received " + mhdr.messageType + ", was expecting ValidateConnection"); } _valid = true; } else { Trace.WriteLine("Received: " + mhdr.messageType); // Process an incoming message. if (mhdr.messageType == MessageType.Request || mhdr.messageType == MessageType.BatchRequest) { if (_requestHandler == null) { throw new InvalidOperationException("Received request, but there's no MRD attached to dispatcher!"); } byte[] msg_rest = _r.ReadBytes(mhdr.messageSize - 14); // 14 is the header MemoryStream ms = new MemoryStream(msg_rest); // this MUST be executed asynchronously, otherwise we are unable to // receive any further requests on this endpoint until it returns. // we might want some better control over this, but for now, let the // runtime take care of scheduling it. _requestHandler.BeginInvoke(_e, ms, mhdr.messageType, null, null); } else if (mhdr.messageType == MessageType.Reply) { int requestId = _r.ReadInt32(); lock (_notifiedRequests) { ManualResetEvent mre; lock (_outstandingRequests) { mre = (ManualResetEvent)_outstandingRequests[requestId]; _outstandingRequests.Remove(requestId); } int bufSize = mhdr.messageSize; byte[] msg = _r.ReadBytes(mhdr.messageSize - 18); // we don't send along the message header, OR the requestId. // the next thing that is read is the reply type, which we // don't care about at this point -- we just suck up the // rest of the message and pass it along. MemoryStream ms = new MemoryStream(msg); _notifiedRequests[requestId] = ms; if (mre == null) { Console.WriteLine("Got Reply for requestId " + requestId + " but had no MRE!"); } else { mre.Set(); } } } else if (mhdr.messageType == MessageType.CloseConnection) { // err -- what do I do here? return; } else { Console.WriteLine("Dispatcher got unhandled message of type " + mhdr.messageType); } } } }