Example #1
0
        /**
         * Internal call method to actually perform the Pyro method call and process the result.
         */
        private object call(string method, int flags, params object[] parameters)
        {
            lock(this) {
            connect();
            unchecked {
                sequenceNr++;        // unchecked so this ushort wraps around 0-65535 instead of raising an OverflowException
            }
            Console.WriteLine("seq="+sequenceNr);
            }
            if (parameters == null)
            parameters = new object[] {};
            object[] invokeparams = new object[] {
                    objectid, method, parameters, // vargs
                    new Hashtable(0)   // no kwargs
                };
            Pickler pickler=new Pickler(false);
            byte[] pickle = pickler.dumps(invokeparams);
            pickler.close();
            byte[] headerdata = MessageFactory.createMsgHeader(MessageFactory.MSG_INVOKE, pickle, flags, sequenceNr);
            Message resultmsg;
            lock (this.sock) {
            IOUtil.send(sock_stream, headerdata);
            IOUtil.send(sock_stream, pickle);
            if(Config.MSG_TRACE_DIR!=null) {
                MessageFactory.TraceMessageSend(sequenceNr, headerdata, pickle);
            }
            pickle = null;
            headerdata = null;

            if ((flags & MessageFactory.FLAGS_ONEWAY) != 0)
                return null;

            resultmsg = MessageFactory.getMessage(sock_stream, MessageFactory.MSG_RESULT);
            }
            if (resultmsg.sequence != sequenceNr) {
            throw new PyroException("result msg out of sync");
            }
            if ((resultmsg.flags & MessageFactory.FLAGS_COMPRESSED) != 0) {
            // we need to skip the first 2 bytes in the buffer due to a tiny mismatch between zlib-written
            // data and the deflate data bytes that .net expects.
            // See http://www.chiramattel.com/george/blog/2007/09/09/deflatestream-block-length-does-not-match.html
            using(MemoryStream compressed=new MemoryStream(resultmsg.data, 2, resultmsg.data.Length-2, false)) {
                using(DeflateStream decompresser=new DeflateStream(compressed, CompressionMode.Decompress)) {
                    MemoryStream bos = new MemoryStream(resultmsg.data.Length);
                    byte[] buffer = new byte[4096];
                    int numRead;
                    while ((numRead = decompresser.Read(buffer, 0, buffer.Length)) != 0) {
                        bos.Write(buffer, 0, numRead);
                    }
                    resultmsg.data=bos.ToArray();
                }
            }
            }
            if ((resultmsg.flags & MessageFactory.FLAGS_EXCEPTION) != 0) {
            using(Unpickler unpickler=new Unpickler()) {
                Exception rx = (Exception) unpickler.loads(resultmsg.data);
                if (rx is PyroException) {
                    throw (PyroException) rx;
                } else {
                    PyroException px = new PyroException("remote exception occurred", rx);
                    PropertyInfo remotetbProperty=rx.GetType().GetProperty("_pyroTraceback");
                    if(remotetbProperty!=null) {
                        string remotetb=(string)remotetbProperty.GetValue(rx,null);
                        px._pyroTraceback=remotetb;
                    }
                    throw px;
                }
            }
            }

            using(Unpickler unpickler=new Unpickler()) {
            return unpickler.loads(resultmsg.data);
            }
        }