void ProcessCall(uint callId, uint type, BufferView data) { object inflatedData; // Check the sequence id if (callId != ++LastReceivedId) { ProtocolError(); return; } // Get call definition Registry.RegisteredCall call = Registry.GetServerCall(type); if (call == null) { ProtocolError(); return; } // Read the incoming data try { inflatedData = InflateData.Inflate(data, call.ArgsFormat); } catch { ProtocolError(); return; } // Emit the "call" event if (OnCall != null) { OnCall(this, new CallEventArgs(call, inflatedData, this, callId)); } }
/// <summary> /// Create a new args bag /// </summary> /// <param name="type">The type of this call</param> /// <param name="data">The inflated data</param> /// <param name="conn">The connection that created this bag</param> /// <param name="call">The call definition</param> /// <param name="callId">The call sequence id</param> internal CallEventArgs(Registry.RegisteredCall call, object data, Connection conn, uint callId) { Data = data; Conn = conn; Call = call; CallId = callId; }
public PendingCall(uint callId, Registry.RegisteredCall call, ReturnDelegate onReturn, ExceptionDelegate onException, Timer interval) { CallId = callId; Call = call; OnReturn = onReturn; OnException = onException; Interval = interval; }
/// <summary> /// Send a call to the server /// </summary> /// <param name="type">The call type (must have been registered with Registry.RegisterClientCall)</param> /// <param name="data">The data pack to send</param> /// <param name="onReturn">The callback to be executed when the server answers this call</param> /// <param name="onException">The callback to be executed when the server answer this call with an exception (or the call timeouts or the connection closes)</param> /// <param name="timeout">The timeout (in ms), 0 means no timeout</param> public void SendCall(uint type, Data data, ReturnDelegate onReturn = null, ExceptionDelegate onException = null, int timeout = 60000) { // Validate the data if (!IsReady) { throw new InvalidOperationException("The connection has already been closed"); } Registry.RegisteredCall call = Registry.GetClientCall(type); if (call == null) { throw new ArgumentException("Invalid call type " + type); } if (data.Format != call.ArgsFormat.FormatString) { throw new ArgumentException("Invalid data type '" + data.Format + "' for call " + type); } // Create the meta-data byte[] binData = data.GetBytes(); byte[] binMeta = new Data().AddUint(type).AddUint(++LastSentId).GetBytes(); byte[] binLength = new Data().AddUint((ulong)(binData.Length + binMeta.Length)).GetBytes(); // Send the call Socket.Write(binLength); Socket.Write(binMeta); Socket.Write(binData); // Set timeout Timer interval = null; if (timeout != 0) { interval = new Timer(timeout); interval.AutoReset = false; interval.Elapsed += TimeoutCallback; interval.Start(); } // Save info about the sent call PendingCalls.AddLast(new PendingCall(LastSentId, call, onReturn, onException, interval)); }