private Protocol Handshake(Decoder input, Encoder output, Transceiver connection) { if (connection != null && connection.IsConnected) { return(connection.Remote); } HandshakeRequest request = handshakeReader.Read(null, input); Protocol remote; lock (protocolsLock) { remote = protocols[request.clientHash.Schema]; if (remote == null && request.clientProtocol != null) { remote = Protocol.Parse(request.clientProtocol); protocols[request.clientHash.Schema] = remote; } } var response = new HandshakeResponse(); if (localHash.Schema.Equals(request.serverHash.Schema)) { response.match = remote == null ? HandshakeMatch.NONE : HandshakeMatch.BOTH; } else { response.match = remote == null ? HandshakeMatch.NONE : HandshakeMatch.CLIENT; } if (response.match != HandshakeMatch.BOTH) { response.serverProtocol = local.ToString(); response.serverHash = localHash; } handshakeWriter.Write(response, output); if (connection != null && response.match != HandshakeMatch.NONE) { connection.Remote = remote; } return(remote); }
public Object getResponse() { Message lm = request.GetMessage(requestor.Local); Message rm; if (!requestor.remoteProtocol.Messages.TryGetValue(request.GetMessage(requestor.Local).Name, out rm)) { throw new AvroRuntimeException ("Not a remote message: " + request.GetMessage(requestor.Local).Name); } Transceiver t = requestor.Transceiver; if ((lm.Oneway.GetValueOrDefault() != rm.Oneway.GetValueOrDefault()) && t.IsConnected) { throw new AvroRuntimeException ("Not both one-way messages: " + request.GetMessage(requestor.Local)); } if (lm.Oneway.GetValueOrDefault() && t.IsConnected) { return(null); // one-way w/ handshake } RpcContext context = request.Context; context.ResponseCallMeta = MetaReader.Read(null, input); if (!input.ReadBoolean()) { // no error Object response = requestor.ReadResponse(rm.Response, lm.Response, input); context.Response = response; return(response); } Exception error = requestor.ReadError(rm.SupportedErrors, lm.SupportedErrors, input); context.Error = error; throw error; }
private Protocol Handshake(Decoder input, Encoder output, Transceiver connection) { if (connection != null && connection.IsConnected) return connection.Remote; HandshakeRequest request = handshakeReader.Read(null, input); Protocol remote; lock (protocolsLock) { remote = protocols[request.clientHash.Schema]; if (remote == null && request.clientProtocol != null) { remote = Protocol.Parse(request.clientProtocol); protocols[request.clientHash.Schema] = remote; } } var response = new HandshakeResponse(); if (localHash.Schema.Equals(request.serverHash.Schema)) { response.match = remote == null ? HandshakeMatch.NONE : HandshakeMatch.BOTH; } else { response.match = remote == null ? HandshakeMatch.NONE : HandshakeMatch.CLIENT; } if (response.match != HandshakeMatch.BOTH) { response.serverProtocol = local.ToString(); response.serverHash = localHash; } handshakeWriter.Write(response, output); if (connection != null && response.match != HandshakeMatch.NONE) connection.Remote = remote; return remote; }
public IList <MemoryStream> Respond(IList <MemoryStream> buffers, Transceiver connection) { Decoder input = new BinaryDecoder(new ByteBufferInputStream(buffers)); var bbo = new ByteBufferOutputStream(); var output = new BinaryEncoder(bbo); Exception error = null; var context = new RpcContext(); List <MemoryStream> handshake = null; bool wasConnected = connection != null && connection.IsConnected; try { Protocol remote = Handshake(input, output, connection); output.Flush(); if (remote == null) // handshake failed { return(bbo.GetBufferList()); } handshake = bbo.GetBufferList(); // read request using remote protocol specification context.RequestCallMeta = META_READER.Read(null, input); String messageName = input.ReadString(); if (messageName.Equals("")) // a handshake ping { return(handshake); } Message rm = remote.Messages[messageName]; if (rm == null) { throw new AvroRuntimeException("No such remote message: " + messageName); } Message m = Local.Messages[messageName]; if (m == null) { throw new AvroRuntimeException("No message named " + messageName + " in " + Local); } Object request = ReadRequest(rm.Request, m.Request, input); context.Message = rm; // create response using local protocol specification if ((m.Oneway.GetValueOrDefault() != rm.Oneway.GetValueOrDefault()) && wasConnected) { throw new AvroRuntimeException("Not both one-way: " + messageName); } Object response = null; try { response = Respond(m, request); context.Response = response; } catch (Exception e) { error = e; context.Error = error; log.Warn("user error", e); } if (m.Oneway.GetValueOrDefault() && wasConnected) // no response data { return(null); } output.WriteBoolean(error != null); if (error == null) { WriteResponse(m.Response, response, output); } else { try { WriteError(m.SupportedErrors, error, output); } catch (Exception) { // Presumably no match on the exception, throw the original throw error; } } } catch (Exception e) { // system error log.Warn("system error", e); context.Error = e; bbo = new ByteBufferOutputStream(); output = new BinaryEncoder(bbo); output.WriteBoolean(true); WriteError(errorSchema /*Protocol.SYSTEM_ERRORS*/, e.ToString(), output); if (null == handshake) { handshake = new ByteBufferOutputStream().GetBufferList(); } } output.Flush(); List <MemoryStream> payload = bbo.GetBufferList(); // Grab meta-data from plugins context.ResponsePayload = payload; META_WRITER.Write(context.ResponseCallMeta, output); output.Flush(); // Prepend handshake and append payload bbo.Prepend(handshake); bbo.Append(payload); return(bbo.GetBufferList()); }
private void Request <T>(RpcRequest request, ICallback <T> callback) { Transceiver t = transceiver; if (!t.IsConnected) { Monitor.Enter(handshakeLock); handshakeThread = Thread.CurrentThread; try { if (!t.IsConnected) { var callFuture = new CallFuture <T>(callback); IList <MemoryStream> bytes = request.GetBytes(Local, this); var transceiverCallback = new TransceiverCallback <T>(this, request, callFuture, Local); t.Transceive(bytes, transceiverCallback); // Block until handshake complete callFuture.Wait(); Message message = GetMessage(request); if (message.Oneway.GetValueOrDefault()) { Exception error = callFuture.Error; if (error != null) { throw error; } } return; } } finally { if (Thread.CurrentThread == handshakeThread) { handshakeThread = null; Monitor.Exit(handshakeLock); } } } if (GetMessage(request).Oneway.GetValueOrDefault()) { t.LockChannel(); try { IList <MemoryStream> bytes = request.GetBytes(Local, this); t.WriteBuffers(bytes); if (callback != null) { callback.HandleResult(default(T)); } } finally { t.UnlockChannel(); } } else { IList <MemoryStream> bytes = request.GetBytes(Local, this); var transceiverCallback = new TransceiverCallback <T>(this, request, callback, Local); t.Transceive(bytes, transceiverCallback); //if (Thread.CurrentThread == handshakeThread) //{ // Monitor.Exit(handshakeLock); //} } }
protected Requestor(Transceiver transceiver, Protocol protocol) { this.transceiver = transceiver; localProtocol = protocol; }
public IList<MemoryStream> Respond(IList<MemoryStream> buffers, Transceiver connection) { Decoder input = new BinaryDecoder(new ByteBufferInputStream(buffers)); var bbo = new ByteBufferOutputStream(); var output = new BinaryEncoder(bbo); Exception error = null; var context = new RpcContext(); List<MemoryStream> handshake = null; bool wasConnected = connection != null && connection.IsConnected; try { Protocol remote = Handshake(input, output, connection); output.Flush(); if (remote == null) // handshake failed return bbo.GetBufferList(); handshake = bbo.GetBufferList(); // read request using remote protocol specification context.RequestCallMeta = META_READER.Read(null, input); String messageName = input.ReadString(); if (messageName.Equals("")) // a handshake ping return handshake; Message rm = remote.Messages[messageName]; if (rm == null) throw new AvroRuntimeException("No such remote message: " + messageName); Message m = Local.Messages[messageName]; if (m == null) throw new AvroRuntimeException("No message named " + messageName + " in " + Local); Object request = ReadRequest(rm.Request, m.Request, input); context.Message = rm; // create response using local protocol specification if ((m.Oneway.GetValueOrDefault() != rm.Oneway.GetValueOrDefault()) && wasConnected) throw new AvroRuntimeException("Not both one-way: " + messageName); Object response = null; try { response = Respond(m, request); context.Response = response; } catch (Exception e) { error = e; context.Error = error; log.Warn("user error", e); } if (m.Oneway.GetValueOrDefault() && wasConnected) // no response data return null; output.WriteBoolean(error != null); if (error == null) WriteResponse(m.Response, response, output); else { try { WriteError(m.SupportedErrors, error, output); } catch (Exception) { // Presumably no match on the exception, throw the original throw error; } } } catch (Exception e) { // system error log.Warn("system error", e); context.Error = e; bbo = new ByteBufferOutputStream(); output = new BinaryEncoder(bbo); output.WriteBoolean(true); WriteError(errorSchema /*Protocol.SYSTEM_ERRORS*/, e.ToString(), output); if (null == handshake) { handshake = new ByteBufferOutputStream().GetBufferList(); } } output.Flush(); List<MemoryStream> payload = bbo.GetBufferList(); // Grab meta-data from plugins context.ResponsePayload = payload; META_WRITER.Write(context.ResponseCallMeta, output); output.Flush(); // Prepend handshake and append payload bbo.Prepend(handshake); bbo.Append(payload); return bbo.GetBufferList(); }