/** Perform the Pyro protocol connection handshake with the Pyro daemon. */ @SuppressWarnings("unchecked") protected void _handshake() throws IOException { // do connection handshake PyroSerializer ser = PyroSerializer.getFor(Config.SERIALIZER); Map<String, Object> handshakedata = new HashMap<String, Object>(); handshakedata.put("handshake", pyroHandshake); if (Config.METADATA) handshakedata.put("object", objectid); byte[] data = ser.serializeData(handshakedata); int flags = Config.METADATA ? Message.FLAGS_META_ON_CONNECT : 0; Message msg = new Message( Message.MSG_CONNECT, data, ser.getSerializerId(), flags, sequenceNr, annotations(), pyroHmacKey); IOUtil.send(sock_out, msg.to_bytes()); if (Config.MSG_TRACE_DIR != null) { Message.TraceMessageSend( sequenceNr, msg.get_header_bytes(), msg.get_annotations_bytes(), msg.data); } // process handshake response msg = Message.recv( sock_in, new int[] {Message.MSG_CONNECTOK, Message.MSG_CONNECTFAIL}, pyroHmacKey); responseAnnotations(msg.annotations, msg.type); Object handshake_response = "?"; if (msg.data != null) { if ((msg.flags & Message.FLAGS_COMPRESSED) != 0) { _decompressMessageData(msg); } handshake_response = ser.deserializeData(msg.data); } if (msg.type == Message.MSG_CONNECTOK) { if ((msg.flags & Message.FLAGS_META_ON_CONNECT) != 0) { HashMap<String, Object> response_dict = (HashMap<String, Object>) handshake_response; HashMap<String, Object> metadata = (HashMap<String, Object>) response_dict.get("meta"); _processMetadata(metadata); handshake_response = response_dict.get("handshake"); try { validateHandshake(handshake_response); } catch (IOException x) { close(); throw x; } } } else if (msg.type == Message.MSG_CONNECTFAIL) { close(); throw new PyroException("connection rejected, reason: " + handshake_response); } else { close(); throw new PyroException("connect: invalid msg type " + msg.type + " received"); } }
/** Internal call method to actually perform the Pyro method call and process the result. */ private Object internal_call( String method, String actual_objectId, int flags, boolean checkMethodName, Object... parameters) throws PickleException, PyroException, IOException { if (actual_objectId == null) actual_objectId = this.objectid; synchronized (this) { connect(); sequenceNr = (sequenceNr + 1) & 0xffff; // stay within an unsigned short 0-65535 } if (pyroAttrs.contains(method)) { throw new PyroException("cannot call an attribute"); } if (pyroOneway.contains(method)) { flags |= Message.FLAGS_ONEWAY; } if (checkMethodName && Config.METADATA && !pyroMethods.contains(method)) { throw new PyroException( String.format( "remote object '%s' has no exposed attribute or method '%s'", actual_objectId, method)); } if (parameters == null) parameters = new Object[] {}; PyroSerializer ser = PyroSerializer.getFor(Config.SERIALIZER); byte[] pickle = ser.serializeCall( actual_objectId, method, parameters, Collections.<String, Object>emptyMap()); Message msg = new Message( Message.MSG_INVOKE, pickle, ser.getSerializerId(), flags, sequenceNr, annotations(), pyroHmacKey); Message resultmsg; synchronized (this.sock) { IOUtil.send(sock_out, msg.to_bytes()); if (Config.MSG_TRACE_DIR != null) { Message.TraceMessageSend( sequenceNr, msg.get_header_bytes(), msg.get_annotations_bytes(), msg.data); } pickle = null; if ((flags & Message.FLAGS_ONEWAY) != 0) return null; resultmsg = Message.recv(sock_in, new int[] {Message.MSG_RESULT}, pyroHmacKey); } if (resultmsg.seq != sequenceNr) { throw new PyroException("result msg out of sync"); } responseAnnotations(resultmsg.annotations, resultmsg.type); if ((resultmsg.flags & Message.FLAGS_COMPRESSED) != 0) { _decompressMessageData(resultmsg); } if ((resultmsg.flags & Message.FLAGS_EXCEPTION) != 0) { Throwable rx = (Throwable) ser.deserializeData(resultmsg.data); if (rx instanceof PyroException) { throw (PyroException) rx; } else { PyroException px = new PyroException("remote exception occurred", rx); try { Field remotetbField = rx.getClass().getDeclaredField("_pyroTraceback"); String remotetb = (String) remotetbField.get(rx); px._pyroTraceback = remotetb; } catch (Exception e) { // exception didn't provide a pyro remote traceback } throw px; } } return ser.deserializeData(resultmsg.data); }