private void HandleCallError(IMessage errorMessage) { int callID = errorMessage.ID; string reason = (string)errorMessage.Result; // Call error with callID = -1 means we've sent something that was not understood by other side or was // malformed. This probably means that protocols aren't incompatible or incorrectly implemented on either // side. if (callID == -1) { throw new Exception(reason); } FuncCallBase failedCall = null; lock (activeCalls) { if (activeCalls.ContainsKey(callID)) { failedCall = activeCalls[callID]; activeCalls.Remove(callID); } } if (failedCall != null) { failedCall.HandleError(reason); } else { Console.WriteLine("One Way Call returned Exception: " + errorMessage.Result); } }
private void HandleCallResponse(IMessage responseMessage) { int callID = responseMessage.ID; FuncCallBase completedCall = null; lock (activeCalls) { if (activeCalls.ContainsKey(callID)) { completedCall = activeCalls[callID]; activeCalls.Remove(callID); } } if (completedCall != null) { bool success = !responseMessage.IsException; object result = responseMessage.Result; if (success) { completedCall.HandleSuccess(result); } else { completedCall.HandleException(new Exception(result as string)); } } else { SendException(-1, "Invalid callID: " + callID); } }
/// <summary> /// Calls a function with a given name and arguments on the remote end. /// </summary> /// <param name="funcName">Function name.</param> /// <param name="args">Argunents.</param> /// <returns>Object representing remote call.</returns> protected virtual IClientFunctionCall CallClientFunction(string funcName, params object[] args) { int callID = getValidCallID(); // Register delegates as callbacks. Pass their registered names instead. List <int> callbacks; List <object> convertedArgs = convertCallbackArguments(args, out callbacks); IMessage callMessage = createRequestMessage(callID, funcName, callbacks, convertedArgs); string[] serviceDescription = funcName.Split('.'); // Usually, a function called via CallClientFunction is parsed from the SINFONI IDL and of the // form serviceName.functionName. However, in some cases (e.g. twisted Unit Tests), functions may be // created locally, only having a GUID as function name. In this case, we appen "LOCAL" as service name // to mark the function as locally created if (serviceDescription.Length < 2) { string[] localService = new string[2]; localService[0] = "LOCAL"; localService[1] = serviceDescription[0]; serviceDescription = localService; } FuncCallBase callObj = null; if (!IsOneWay(funcName)) { callObj = new FuncCallBase(serviceDescription[0], serviceDescription[1], this); // It is important to add an active call to the list before sending it, otherwise we may end up // receiving call-reply before this happens, which will trigger unnecessary call-error and crash the // other end. lock (activeCalls) activeCalls.Add(callID, callObj); } SendMessage(callMessage); return(callObj); }