Exemplo n.º 1
0
        //
        // 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);
                    }
                }
            }
        }