/// <summary> /// Create the proxy to the native session /// </summary> /// <returns></returns> public INativeSession CreateNativeSessionProxy() { INativeSession sessionClient = null; if (NativeServiceClientFactory == null) { lock (NativeServiceClientFactoryLock) { if (NativeServiceClientFactory == null) { if (Session == null) { throw new Exception("Session is null"); } string endpointAddressString = // get string form of address NativeSessionEndpointAddress.Build(Session.ProcessId); Uri endpointUri = new Uri(endpointAddressString); EndpointAddress endpointAddress = new EndpointAddress(endpointUri, ServiceEndpointIdentity); string endpointConfigurationName = "NativeSession_TCPEndpoint"; NativeServiceClientFactory = new ChannelFactory <INativeSession>(endpointConfigurationName, endpointAddress); } } } sessionClient = NativeServiceClientFactory.CreateChannel(); // create channel to new client return(sessionClient); }
/// <summary> /// Invoke service method thread method /// </summary> /// <param name="nativeClient"></param> /// <param name="serviceCodeInt"></param> /// <param name="opCodeInt"></param> /// <param name="argObject"></param> void InvokeNativeMethodThread( INativeSession nativeClient, int serviceCodeInt, int opCodeInt, NativeMethodTransportObject argObject) { object resultObj = null; try { InvokeNativeMethodEntered = true; resultObj = nativeClient.InvokeNativeMethod(serviceCodeInt, opCodeInt, argObject); InvokeNativeMethodResult = resultObj as NativeMethodTransportObject; //if (xxxNativeMethodInvoker.ServiceCallCount == 10) throw new Exception("There was no endpoint listening"); // debug if (InvokeNativeMethodResult != null) { return; } else { throw new Exception("Null result returned"); } } catch (Exception ex) // unexpected exception { InvokeNativeMethodResult = null; InvokeNativeMethodException = ex; return; } }
/// <summary> /// Call native method & process any exception /// </summary> /// <param name="nativeClient"></param> /// <param name="serviceCode"></param> /// <param name="opCode"></param> /// <param name="argObject"></param> /// <returns></returns> public static NativeMethodTransportObject InvokeNativeMethod( INativeSession nativeClient, int serviceCodeInt, int opCodeInt, NativeMethodTransportObject argObject) { NativeMethodTransportObject resultObj = NativeSessionClient.InvokeNativeMethod(nativeClient, serviceCodeInt, opCodeInt, argObject); return(resultObj); }
/// <summary> /// Call native method & process any exception /// </summary> /// <param name="nativeClient"></param> /// <param name="serviceCode"></param> /// <param name="opCode"></param> /// <param name="argObject"></param> /// <returns></returns> public NativeMethodTransportObject InvokeNativeMethod( INativeSession nativeClient, int serviceCodeInt, int opCodeInt, NativeMethodTransportObject transportObject) { NativeMethodInvokerInstance = new NativeMethodInvoker(); NativeMethodTransportObject resultObject = NativeMethodInvokerInstance.InvokeNativeMethod( nativeClient, serviceCodeInt, opCodeInt, transportObject); return(resultObject); }
/// <summary> /// Call a service method and return result /// </summary> /// <param name="serviceCode"></param> /// <param name="subServiceCode"></param> /// <param name="parameters"></param> /// <returns></returns> public NativeMethodTransportObject CallServiceMethod( ServiceCodes serviceCode, object subServiceCode, object parameters) { INativeSession nativeClient = CreateNativeSessionProxy(); NativeMethodInvokerInstance = new NativeMethodInvoker(); Services.Native.NativeMethodTransportObject resultObject = NativeMethodInvokerInstance.InvokeNativeMethod( nativeClient, (int)serviceCode, (int)subServiceCode, new NativeMethodTransportObject(parameters)); ((IClientChannel)nativeClient).Close(); return(resultObject); }
internal void InvokeNativeMethod( INativeSession nativeClient, int serviceCodeInt, int opCodeInt, NativeMethodTransportObject argObject) { //NativeMethodInvoker.ServiceCallSyncLock.WaitOne(); // get the mutex (beware of deadlocks) if (SynchronizationContext.Current is WindowsFormsSynchronizationContext && NativeMethodInvoker.RunUIServiceCallsOnSeparateThread) { // do in separate thread if this is the UI thread ThreadStart ts = delegate() { InvokeNativeMethodThread(nativeClient, serviceCodeInt, opCodeInt, argObject); }; Thread workerThread = new Thread(ts); workerThread.Name = "InvokeNativeMethod " + serviceCodeInt + ", " + opCodeInt; workerThread.IsBackground = true; workerThread.SetApartmentState(ApartmentState.STA); InvokeNativeMethodResult = null; InvokeNativeMethodException = null; InvokeNativeMethodEntered = false; workerThread.Start(); while (!InvokeNativeMethodEntered) { Thread.Sleep(1); // loop until worker thread activates and the method is entered } while (workerThread.IsAlive) { if (InvokeNativeMethodResult != null || InvokeNativeMethodException != null) { break; } Thread.Sleep(2); Application.DoEvents(); } //NativeMethodInvoker.ServiceCallSyncLock.ReleaseMutex(); // release after call (keeps other non-UI threads from making calls until we are complete) } else // non-UI thread, just call directly { //NativeMethodInvoker.ServiceCallSyncLock.ReleaseMutex(); // release before call InvokeNativeMethodThread(nativeClient, serviceCodeInt, opCodeInt, argObject); } return; }
/// <summary> /// Call native method & process any exception /// </summary> /// <param name="nativeClient"></param> /// <param name="serviceCode"></param> /// <param name="opCode"></param> /// <param name="argObject"></param> /// <returns></returns> public NativeMethodTransportObject InvokeNativeMethod( INativeSession nativeClient, int serviceCodeInt, int opCodeInt, NativeMethodTransportObject transportObject) { NativeMethodTransportObject resultObj = null; string servicesExceptionHeader = "*** InvokeNativeMethod Exception ***\r\n"; // this exception header is added by the services upon an exception bool isException = false; int t0 = 0; string classAndMethod = "", msg = "", exceptionType = ""; if (LogServiceCalls) { t0 = ComOps.TimeOfDay.Milliseconds(); classAndMethod = DebugLog.GetCallingClassAndMethodPrefix(); if (IDebugLog != null) { IDebugLog.Message("[ServiceCallBegin]" + classAndMethod + "Begin"); } } DateTime callStart = DateTime.Now; if (ServiceCallCount == 0) { FirstServiceCallTime = DateTime.Now; } LastServiceCallTime = DateTime.Now; NativeMethodCaller nmc = new NativeMethodCaller(); InServiceCall = true; nmc.InvokeNativeMethod(nativeClient, serviceCodeInt, opCodeInt, transportObject); resultObj = nmc.InvokeNativeMethodResult; // any result returned InServiceCall = false; ServiceCallCount++; // count it as complete // Regular exception thown on the client? if (nmc.InvokeNativeMethodException != null) { isException = true; msg = DebugLog.FormatExceptionMessage(nmc.InvokeNativeMethodException); // Check if link to services no longer exists (e.g. Server process killed or Mobius server restarted) if (Lex.Contains(msg, "There was no endpoint listening") || Lex.Contains(msg, "Count not connect") || Lex.Contains(msg, "A connection attempt failed")) // && ServiceCallCount > 1) { msg = @"The connection to Mobius services has been lost. Session start time: {0:G}, Service Calls: {1}, Last service call: {2:G}) Do you want to restart the Mobius client?"; msg = String.Format(msg, FirstServiceCallTime, ServiceCallCount, LastServiceCallTime); DebugLog.Message(msg); DialogResult dr = MessageBox.Show(msg, "No connection to Mobius services", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Error); if (dr == DialogResult.Yes) { Process p = Process.Start(Application.ExecutablePath); } Environment.Exit(-1); } } // Check if exception from services by looking at header in string passed back from services else if (resultObj != null && resultObj.Value is string && (resultObj.Value as string).StartsWith(servicesExceptionHeader)) { isException = true; msg = (resultObj.Value as string).Substring(servicesExceptionHeader.Length); int i1 = msg.IndexOf("\n"); exceptionType = msg.Substring(0, i1 - 1); msg = msg.Substring(i1 + 1); } if (!isException) { if (LogServiceCalls) { t0 = ComOps.TimeOfDay.Milliseconds() - t0; if (IDebugLog != null) { IDebugLog.Message("[ServiceCallEnd]" + classAndMethod + " Time: " + t0 + " ms"); } } return(resultObj); // normal return value } else // the call threw an exception { bool userQueryException = Lex.Eq(exceptionType, "UserQueryException"); bool queryException = Lex.Eq(exceptionType, "QueryException"); if (IDebugLog != null && !userQueryException) { IDebugLog.Message(msg); // log any exceptions except user query exception } if (userQueryException) { throw new UserQueryException(msg); } else if (queryException) { throw new QueryException(msg); } else { throw new Exception(msg); } } }
/// <summary> /// ExecuteLongRunningCommand /// </summary> /// <param name="longRunningCommandObject"></param> public static void ExecuteLongRunningCommand(object longRunningCommandObject) { //Assume that the invocation of this was already outside of the gui thread // -- a good thing since we're going to "sleep" between status polls... LongRunningCommand longRunningCommand = (LongRunningCommand)longRunningCommandObject; if (ServiceFacade.UseRemoteServices) { //verify the taskType client-side... // no reason to make a round-trip to the server if we can fail faster Services.Native.ScheduledTaskTypes taskType = (ScheduledTaskTypes)Enum.Parse( typeof(ScheduledTaskTypes), longRunningCommand.Command); INativeSession nativeClient = ServiceFacade.CreateNativeSessionProxy(); Services.Native.NativeMethodTransportObject resultObject = ServiceFacade.InvokeNativeMethod(nativeClient, (int)ServiceCodes.MobiusTaskSchedulerService, (int)MobiusTaskSchedulerService.SubmitJob, new Services.Native.NativeMethodTransportObject(new object[] { (int)taskType, longRunningCommand.CommandArgs })); Services.Native.ScheduledTask task = (Services.Native.ScheduledTask)resultObject.Value; if (task != null) { //do a SHORT sleep before the first check in case the task failed or completed very quickly task.SuggestedTimeBetweenPolls = TimeSpan.FromSeconds(0.03); while (task.Status == ScheduledTaskStatus.Running) { if (longRunningCommand.UpdateProgress != null && task.Result != null && !String.IsNullOrEmpty(task.Result.ToString())) { longRunningCommand.UpdateProgress(task.Result.ToString(), ComOps.UmlautMobius.String, longRunningCommand.AllowCancel); } Thread.Sleep(task.SuggestedTimeBetweenPolls); resultObject = ServiceFacade.InvokeNativeMethod(nativeClient, (int)ServiceCodes.MobiusTaskSchedulerService, (int)MobiusTaskSchedulerService.CheckJobStatus, new Services.Native.NativeMethodTransportObject(new object[] { task.JobId })); task = (Services.Native.ScheduledTask)resultObject.Value; } longRunningCommand.Result = task.Result; } ((System.ServiceModel.IClientChannel)nativeClient).Close(); longRunningCommand.IsRunning = false; longRunningCommand.SignalCompletion(); if (longRunningCommand.OnCompletion != null) { longRunningCommand.OnCompletion(); } if (longRunningCommand.HideProgress != null) { longRunningCommand.HideProgress(); } if (longRunningCommand.ShowResponse != null && task.Result != null) { longRunningCommand.ShowResponse(task.Result.ToString()); } } }