/** * 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); } }