/// <summary> /// /// </summary> public void ProcessMessage(IMessage requestMessage, ITransportHeaders requestHeaders, Stream requestStream, out ITransportHeaders responseHeaders, out Stream responseStream) { object returnValue = null; responseHeaders = null; responseStream = new MemoryStream(); IMessage responseMsg = null; IMethodCallMessage mcm = requestMessage as IMethodCallMessage; BinaryFormatter bf = new BinaryFormatter(); try { if (_endpoint.StartsWith(WorkflowDefaults.WorkflowLocalhost)) { #region Invoke local Workflow LogicalWorkflowContext lwc = LCC.LogicalWorkflowContext; Guid workflowInstanceId = lwc.GetAndClearWorkflowId(); bool bGetWorkflowById = !workflowInstanceId.Equals(Guid.Empty); // create workflow Invoker invoker = null; if (bGetWorkflowById) { invoker = WorkflowInvoker.Create(workflowInstanceId); } else { string endpoint = _endpoint.Replace(WorkflowDefaults.WorkflowLocalhost, "").Trim('/'); Type workflowType = RemotingServices.GetServerTypeForUri(endpoint); invoker = WorkflowInvoker.Create(workflowType, lwc.WorkflowInitData); } // send remoting message invoker.SendMessage(mcm); // handle response if (RemotingServices.IsOneWay(mcm.MethodBase) == false) { invoker.WaitForResponse(_Sender.TimeOut); returnValue = invoker.GetResponse <object>(); } #endregion } else if (_endpoint.StartsWith(WorkflowDefaults.WorkflowByWCF)) { #region Invoke remote Workflow by WCF try { string endpoint = _endpoint.Replace(WorkflowDefaults.WorkflowByWCF, "").Trim('/'); using (ChannelFactory2 factory = new ChannelFactory2(Type.GetType(mcm.TypeName), endpoint)) { object tp = factory.CreateChannel(); using (OperationContextScope scope = new OperationContextScope(tp as IContextChannel)) { // CallContext over the loosely coupled contract (LogicalWorkflowContext and Unknown) object lwc = LCC.GetLogicalWorkflowContext; if (lwc != null) { MessageHeader header = MessageHeader.CreateHeader("LogicalWorkflowContext", "RKiss.WorkflowRemoting", lwc, false, "WorkflowRemoting"); OperationContext.Current.OutgoingMessageHeaders.Add(header); } if (!string.IsNullOrEmpty(Sender.CallContextActor)) { IDictionaryEnumerator enumerator = LCC.GetDataContract().GetEnumerator(); while (enumerator.MoveNext()) { // skip it if (enumerator.Value is LogicalWorkflowContext) { continue; } DataContractAttribute dca = enumerator.Key as DataContractAttribute; MessageHeader header = MessageHeader.CreateHeader(dca.Name, dca.Namespace, enumerator.Value, false, Sender.CallContextActor); OperationContext.Current.OutgoingMessageHeaders.Add(header); } } // action returnValue = factory.InvokeMethod(mcm.MethodName, mcm.Args); } factory.Close(); } } catch (TargetInvocationException ex) { throw ex.InnerException; } catch (Exception ex) { throw ex; } #endregion } else { throw new InvalidOperationException("No supported schema"); } // return value responseMsg = (IMessage) new ReturnMessage(returnValue, null, 0, null, mcm); } catch (System.ServiceModel.FaultException fe) { Exception ex = new Exception(fe.Message); ex.GetType().InvokeMember("_stackTraceString", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Instance, null, ex, new object[] { fe.ToString() }); responseMsg = new ReturnMessage(ex, mcm); } catch (Exception ex) { responseMsg = new ReturnMessage(ex, mcm); } finally { #region serialize IMessage response to return back bf.Serialize(responseStream, responseMsg); responseStream.Position = 0; responseHeaders = requestHeaders; #endregion } }
/// <summary> /// /// </summary> public void ProcessMessage(IMessage requestMessage, ITransportHeaders requestHeaders, Stream requestStream, out ITransportHeaders responseHeaders, out Stream responseStream) { object returnValue = null; responseHeaders = null; responseStream = new MemoryStream(); IMessage responseMsg = null; IMethodCallMessage mcm = requestMessage as IMethodCallMessage; BinaryFormatter bf = new BinaryFormatter(); try { if (_endpoint.StartsWith(WorkflowDefaults.WorkflowLocalhost)) { #region Invoke local Workflow LogicalWorkflowContext lwc = LCC.LogicalWorkflowContext; Guid workflowInstanceId = lwc.GetAndClearWorkflowId(); bool bGetWorkflowById = !workflowInstanceId.Equals(Guid.Empty); // create workflow Invoker invoker = null; if (bGetWorkflowById) { invoker = WorkflowInvoker.Create(workflowInstanceId); } else { string endpoint = _endpoint.Replace(WorkflowDefaults.WorkflowLocalhost, "").Trim('/'); Type workflowType = RemotingServices.GetServerTypeForUri(endpoint); invoker = WorkflowInvoker.Create(workflowType, lwc.WorkflowInitData); } // send remoting message invoker.SendMessage(mcm); // handle response if (RemotingServices.IsOneWay(mcm.MethodBase) == false) { invoker.WaitForResponse(_Sender.TimeOut); returnValue = invoker.GetResponse<object>(); } #endregion } else if (_endpoint.StartsWith(WorkflowDefaults.WorkflowByWCF)) { #region Invoke remote Workflow by WCF try { string endpoint = _endpoint.Replace(WorkflowDefaults.WorkflowByWCF, "").Trim('/'); using (ChannelFactory2 factory = new ChannelFactory2(Type.GetType(mcm.TypeName), endpoint)) { object tp = factory.CreateChannel(); using (OperationContextScope scope = new OperationContextScope(tp as IContextChannel)) { // CallContext over the loosely coupled contract (LogicalWorkflowContext and Unknown) object lwc = LCC.GetLogicalWorkflowContext; if (lwc != null) { MessageHeader header = MessageHeader.CreateHeader("LogicalWorkflowContext", "RKiss.WorkflowRemoting", lwc, false, "WorkflowRemoting"); OperationContext.Current.OutgoingMessageHeaders.Add(header); } if (!string.IsNullOrEmpty(Sender.CallContextActor)) { IDictionaryEnumerator enumerator = LCC.GetDataContract().GetEnumerator(); while (enumerator.MoveNext()) { // skip it if (enumerator.Value is LogicalWorkflowContext) continue; DataContractAttribute dca = enumerator.Key as DataContractAttribute; MessageHeader header = MessageHeader.CreateHeader(dca.Name, dca.Namespace, enumerator.Value, false, Sender.CallContextActor); OperationContext.Current.OutgoingMessageHeaders.Add(header); } } // action returnValue = factory.InvokeMethod(mcm.MethodName, mcm.Args); } factory.Close(); } } catch (TargetInvocationException ex) { throw ex.InnerException; } catch (Exception ex) { throw ex; } #endregion } else { throw new InvalidOperationException("No supported schema"); } // return value responseMsg = (IMessage)new ReturnMessage(returnValue, null, 0, null, mcm); } catch (System.ServiceModel.FaultException fe) { Exception ex = new Exception(fe.Message); ex.GetType().InvokeMember("_stackTraceString", BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Instance, null, ex, new object[] { fe.ToString() }); responseMsg = new ReturnMessage(ex, mcm); } catch (Exception ex) { responseMsg = new ReturnMessage(ex, mcm); } finally { #region serialize IMessage response to return back bf.Serialize(responseStream, responseMsg); responseStream.Position = 0; responseHeaders = requestHeaders; #endregion } }