SEBWIN-219: Extended IPC mechanics with ping mechanism.
This commit is contained in:
parent
268eda9f90
commit
8a06a0fe98
15 changed files with 263 additions and 63 deletions
|
@ -12,6 +12,7 @@ using SafeExamBrowser.Contracts.Behaviour.Operations;
|
|||
using SafeExamBrowser.Contracts.Communication;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||
using SafeExamBrowser.Contracts.I18n;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.Monitoring;
|
||||
using SafeExamBrowser.Contracts.UserInterface;
|
||||
|
@ -81,13 +82,21 @@ namespace SafeExamBrowser.Client.Behaviour
|
|||
|
||||
var success = operations.TryPerform();
|
||||
|
||||
// TODO
|
||||
|
||||
if (success)
|
||||
{
|
||||
RegisterEvents();
|
||||
// TODO: Handle communication exception!
|
||||
runtime.InformClientReady();
|
||||
|
||||
try
|
||||
{
|
||||
runtime.InformClientReady();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error("Failed to inform runtime that client is ready!", e);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
splashScreen.Hide();
|
||||
|
||||
logger.Info("--- Application successfully initialized ---");
|
||||
|
@ -110,9 +119,8 @@ namespace SafeExamBrowser.Client.Behaviour
|
|||
splashScreen.Show();
|
||||
splashScreen.BringToForeground();
|
||||
|
||||
// TODO
|
||||
|
||||
DeregisterEvents();
|
||||
|
||||
var success = operations.TryRevert();
|
||||
|
||||
if (success)
|
||||
|
@ -134,6 +142,7 @@ namespace SafeExamBrowser.Client.Behaviour
|
|||
ClientHost.Shutdown += ClientHost_Shutdown;
|
||||
displayMonitor.DisplayChanged += DisplayMonitor_DisplaySettingsChanged;
|
||||
processMonitor.ExplorerStarted += ProcessMonitor_ExplorerStarted;
|
||||
runtime.ConnectionLost += Runtime_ConnectionLost;
|
||||
taskbar.QuitButtonClicked += Taskbar_QuitButtonClicked;
|
||||
windowMonitor.WindowChanged += WindowMonitor_WindowChanged;
|
||||
}
|
||||
|
@ -143,6 +152,7 @@ namespace SafeExamBrowser.Client.Behaviour
|
|||
ClientHost.Shutdown -= ClientHost_Shutdown;
|
||||
displayMonitor.DisplayChanged -= DisplayMonitor_DisplaySettingsChanged;
|
||||
processMonitor.ExplorerStarted -= ProcessMonitor_ExplorerStarted;
|
||||
runtime.ConnectionLost -= Runtime_ConnectionLost;
|
||||
taskbar.QuitButtonClicked -= Taskbar_QuitButtonClicked;
|
||||
windowMonitor.WindowChanged -= WindowMonitor_WindowChanged;
|
||||
}
|
||||
|
@ -173,11 +183,31 @@ namespace SafeExamBrowser.Client.Behaviour
|
|||
shutdown.Invoke();
|
||||
}
|
||||
|
||||
private void Runtime_ConnectionLost()
|
||||
{
|
||||
logger.Error("Lost connection to the runtime!");
|
||||
uiFactory.Show(TextKey.MessageBox_ApplicationError, TextKey.MessageBox_ApplicationErrorTitle, icon: MessageBoxIcon.Error);
|
||||
|
||||
taskbar.Close();
|
||||
shutdown.Invoke();
|
||||
}
|
||||
|
||||
private void Taskbar_QuitButtonClicked()
|
||||
{
|
||||
// TODO: MessageBox asking whether user really wants to quit -> only then request shutdown!
|
||||
// TODO: Handle communication exception!
|
||||
runtime.RequestShutdown();
|
||||
var result = uiFactory.Show(TextKey.MessageBox_Quit, TextKey.MessageBox_QuitTitle, MessageBoxAction.YesNo, MessageBoxIcon.Question);
|
||||
|
||||
if (result == MessageBoxResult.Yes)
|
||||
{
|
||||
try
|
||||
{
|
||||
runtime.RequestShutdown();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error("Failed to communicate shutdown request to the runtime!", e);
|
||||
uiFactory.Show(TextKey.MessageBox_QuitError, TextKey.MessageBox_QuitErrorTitle, icon: MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void WindowMonitor_WindowChanged(IntPtr window)
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace SafeExamBrowser.Client.Communication
|
|||
{
|
||||
internal class ClientHost : BaseHost, IClientHost
|
||||
{
|
||||
private bool allowConnection = true;
|
||||
private int processId;
|
||||
|
||||
public Guid StartupToken { private get; set; }
|
||||
|
@ -30,18 +31,24 @@ namespace SafeExamBrowser.Client.Communication
|
|||
|
||||
protected override bool OnConnect(Guid? token)
|
||||
{
|
||||
return StartupToken == token;
|
||||
var authenticated = StartupToken == token;
|
||||
var accepted = allowConnection && authenticated;
|
||||
|
||||
if (accepted)
|
||||
{
|
||||
allowConnection = false;
|
||||
}
|
||||
|
||||
return accepted;
|
||||
}
|
||||
|
||||
protected override void OnDisconnect()
|
||||
{
|
||||
// TODO
|
||||
// Nothing to do here...
|
||||
}
|
||||
|
||||
protected override Response OnReceive(Message message)
|
||||
{
|
||||
// TODO
|
||||
|
||||
return new SimpleResponse(SimpleResponsePurport.UnknownMessage);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,13 @@ namespace SafeExamBrowser.Contracts.Communication
|
|||
public interface ICommunicationProxy
|
||||
{
|
||||
/// <summary>
|
||||
/// Tries to establish a connection. Returns <c>true</c> if the connection has been accepted, otherwise <c>false</c>.
|
||||
/// Fired when the connection to the proxy was lost, e.g. if a ping request failed or a communication fault occurred.
|
||||
/// </summary>
|
||||
event CommunicationEventHandler ConnectionLost;
|
||||
|
||||
/// <summary>
|
||||
/// Tries to establish a connection. Returns <c>true</c> if the connection has been accepted, otherwise <c>false</c>. If a
|
||||
/// connection was successfully established, a ping mechanism will be activated to periodically check the connection status.
|
||||
/// </summary>
|
||||
/// <exception cref="System.ServiceModel.*">If the communication failed.</exception>
|
||||
bool Connect(Guid? token = null);
|
||||
|
|
|
@ -11,7 +11,7 @@ using System;
|
|||
namespace SafeExamBrowser.Contracts.Communication.Messages
|
||||
{
|
||||
[Serializable]
|
||||
public class Message
|
||||
public abstract class Message
|
||||
{
|
||||
/// <summary>
|
||||
/// The communication token needed for authentication.
|
||||
|
|
|
@ -28,6 +28,11 @@ namespace SafeExamBrowser.Contracts.Communication.Messages
|
|||
/// </summary>
|
||||
ConfigurationNeeded,
|
||||
|
||||
/// <summary>
|
||||
/// Requests an interlocutor to signal that the connection status is okay.
|
||||
/// </summary>
|
||||
Ping,
|
||||
|
||||
/// <summary>
|
||||
/// Sent from the client to the runtime to request shutting down the application.
|
||||
/// </summary>
|
||||
|
|
|
@ -11,7 +11,7 @@ using System;
|
|||
namespace SafeExamBrowser.Contracts.Communication.Responses
|
||||
{
|
||||
[Serializable]
|
||||
public class Response
|
||||
public abstract class Response
|
||||
{
|
||||
public override string ToString()
|
||||
{
|
||||
|
|
|
@ -15,10 +15,18 @@ namespace SafeExamBrowser.Contracts.I18n
|
|||
{
|
||||
Browser_ShowDeveloperConsole,
|
||||
LogWindow_Title,
|
||||
MessageBox_ApplicationError,
|
||||
MessageBox_ApplicationErrorTitle,
|
||||
MessageBox_ConfigureClientSuccess,
|
||||
MessageBox_ConfigureClientSuccessTitle,
|
||||
MessageBox_Quit,
|
||||
MessageBox_QuitTitle,
|
||||
MessageBox_QuitError,
|
||||
MessageBox_QuitErrorTitle,
|
||||
MessageBox_SessionStartError,
|
||||
MessageBox_SessionStartErrorTitle,
|
||||
MessageBox_SessionStopError,
|
||||
MessageBox_SessionStopErrorTitle,
|
||||
MessageBox_ShutdownError,
|
||||
MessageBox_ShutdownErrorTitle,
|
||||
MessageBox_SingleInstance,
|
||||
|
|
|
@ -101,13 +101,17 @@ namespace SafeExamBrowser.Core.Communication
|
|||
|
||||
if (IsAuthorized(message?.CommunicationToken))
|
||||
{
|
||||
if (message is SimpleMessage simpleMessage)
|
||||
switch (message)
|
||||
{
|
||||
response = OnReceive(simpleMessage.Purport);
|
||||
}
|
||||
else
|
||||
{
|
||||
response = OnReceive(message);
|
||||
case SimpleMessage simpleMessage when simpleMessage.Purport == SimpleMessagePurport.Ping:
|
||||
response = new SimpleResponse(SimpleResponsePurport.Acknowledged);
|
||||
break;
|
||||
case SimpleMessage simpleMessage:
|
||||
response = OnReceive(simpleMessage.Purport);
|
||||
break;
|
||||
default:
|
||||
response = OnReceive(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,7 +222,7 @@ namespace SafeExamBrowser.Core.Communication
|
|||
|
||||
private void Host_Faulted(object sender, EventArgs e)
|
||||
{
|
||||
logger.Debug("Communication host has faulted!");
|
||||
logger.Error("Communication host has faulted!");
|
||||
}
|
||||
|
||||
private void Host_Opened(object sender, EventArgs e)
|
||||
|
@ -233,7 +237,7 @@ namespace SafeExamBrowser.Core.Communication
|
|||
|
||||
private void Host_UnknownMessageReceived(object sender, UnknownMessageReceivedEventArgs e)
|
||||
{
|
||||
logger.Debug($"Communication host has received an unknown message: {e?.Message}.");
|
||||
logger.Warn($"Communication host has received an unknown message: {e?.Message}.");
|
||||
}
|
||||
|
||||
private string ToString(Message message)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
using System;
|
||||
using System.ServiceModel;
|
||||
using System.Timers;
|
||||
using SafeExamBrowser.Contracts.Communication;
|
||||
using SafeExamBrowser.Contracts.Communication.Messages;
|
||||
using SafeExamBrowser.Contracts.Communication.Responses;
|
||||
|
@ -17,12 +18,18 @@ namespace SafeExamBrowser.Core.Communication
|
|||
{
|
||||
public abstract class BaseProxy : ICommunicationProxy
|
||||
{
|
||||
private const int ONE_MINUTE = 60000;
|
||||
private static readonly object @lock = new object();
|
||||
|
||||
private string address;
|
||||
private ICommunication channel;
|
||||
private Guid? communicationToken;
|
||||
private Timer timer;
|
||||
|
||||
protected ILogger Logger { get; private set; }
|
||||
|
||||
public event CommunicationEventHandler ConnectionLost;
|
||||
|
||||
public BaseProxy(string address, ILogger logger)
|
||||
{
|
||||
this.address = address;
|
||||
|
@ -47,12 +54,18 @@ namespace SafeExamBrowser.Core.Communication
|
|||
communicationToken = response.CommunicationToken;
|
||||
Logger.Debug($"Connection was {(response.ConnectionEstablished ? "established" : "refused")}.");
|
||||
|
||||
if (response.ConnectionEstablished)
|
||||
{
|
||||
StartAutoPing();
|
||||
}
|
||||
|
||||
return response.ConnectionEstablished;
|
||||
}
|
||||
|
||||
public virtual bool Disconnect()
|
||||
{
|
||||
FailIfNotConnected(nameof(Disconnect));
|
||||
StopAutoPing();
|
||||
|
||||
var message = new DisconnectionMessage { CommunicationToken = communicationToken.Value };
|
||||
var response = channel.Disconnect(message);
|
||||
|
@ -80,6 +93,11 @@ namespace SafeExamBrowser.Core.Communication
|
|||
return Send(new SimpleMessage(purport));
|
||||
}
|
||||
|
||||
protected bool IsAcknowledged(Response response)
|
||||
{
|
||||
return response is SimpleResponse simpleResponse && simpleResponse.Purport == SimpleResponsePurport.Acknowledged;
|
||||
}
|
||||
|
||||
protected string ToString(Message message)
|
||||
{
|
||||
return message != null ? message.ToString() : "<null>";
|
||||
|
@ -102,7 +120,8 @@ namespace SafeExamBrowser.Core.Communication
|
|||
|
||||
private void BaseProxy_Faulted(object sender, EventArgs e)
|
||||
{
|
||||
Logger.Debug("Communication channel has faulted!");
|
||||
Logger.Error("Communication channel has faulted!");
|
||||
ConnectionLost?.Invoke();
|
||||
}
|
||||
|
||||
private void BaseProxy_Opened(object sender, EventArgs e)
|
||||
|
@ -132,5 +151,54 @@ namespace SafeExamBrowser.Core.Communication
|
|||
{
|
||||
return channel == null ? "null" : $"in state '{(channel as ICommunicationObject).State}'";
|
||||
}
|
||||
|
||||
private void StartAutoPing()
|
||||
{
|
||||
lock (@lock)
|
||||
{
|
||||
timer = new Timer(ONE_MINUTE) { AutoReset = true };
|
||||
timer.Elapsed += Timer_Elapsed;
|
||||
timer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
private void StopAutoPing()
|
||||
{
|
||||
lock (@lock)
|
||||
{
|
||||
timer?.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void Timer_Elapsed(object sender, ElapsedEventArgs args)
|
||||
{
|
||||
lock (@lock)
|
||||
{
|
||||
if (timer.Enabled)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = Send(SimpleMessagePurport.Ping);
|
||||
|
||||
if (IsAcknowledged(response))
|
||||
{
|
||||
Logger.Info("Pinged proxy, connection is alive.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Error($"Proxy did not acknowledge ping message! Received: {ToString(response)}.");
|
||||
timer.Stop();
|
||||
ConnectionLost?.Invoke();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error("Failed to ping proxy!", e);
|
||||
timer.Stop();
|
||||
ConnectionLost?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System.ServiceModel;
|
||||
using SafeExamBrowser.Contracts.Communication;
|
||||
using SafeExamBrowser.Contracts.Communication.Messages;
|
||||
using SafeExamBrowser.Contracts.Communication.Responses;
|
||||
|
@ -23,9 +24,9 @@ namespace SafeExamBrowser.Core.Communication
|
|||
{
|
||||
var response = Send(SimpleMessagePurport.Shutdown);
|
||||
|
||||
if (response is SimpleResponse simpleMessage && simpleMessage.Purport == SimpleResponsePurport.Acknowledged)
|
||||
if (!IsAcknowledged(response))
|
||||
{
|
||||
// TODO
|
||||
throw new CommunicationException($"Runtime did not acknowledge shutdown request! Received: {ToString(response)}.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +34,12 @@ namespace SafeExamBrowser.Core.Communication
|
|||
{
|
||||
var response = Send(SimpleMessagePurport.Authenticate);
|
||||
|
||||
return response as AuthenticationResponse;
|
||||
if (response is AuthenticationResponse authenticationResponse)
|
||||
{
|
||||
return authenticationResponse;
|
||||
}
|
||||
|
||||
throw new CommunicationException($"Did not receive authentication response! Received: {ToString(response)}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,10 +52,5 @@ namespace SafeExamBrowser.Core.Communication
|
|||
throw new CommunicationException($"Runtime did not acknowledge shutdown request! Response: {ToString(response)}.");
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsAcknowledged(Response response)
|
||||
{
|
||||
return response is SimpleResponse simpleResponse && simpleResponse.Purport == SimpleResponsePurport.Acknowledged;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,18 +6,42 @@
|
|||
<Entry key="LogWindow_Title">
|
||||
Application Log
|
||||
</Entry>
|
||||
<Entry key="MessageBox_ApplicationError">
|
||||
An unrecoverable error has occurred! Please consult the application log for more information. The application will now shut down...
|
||||
</Entry>
|
||||
<Entry key="MessageBox_ApplicationErrorTitle">
|
||||
Application Error
|
||||
</Entry>
|
||||
<Entry key="MessageBox_ConfigureClientSuccess">
|
||||
The client configuration has been saved and will be used when you start the application the next time. Do you want to quit for now?
|
||||
</Entry>
|
||||
<Entry key="MessageBox_ConfigureClientSuccessTitle">
|
||||
Configuration Successful
|
||||
</Entry>
|
||||
<Entry key="MessageBox_Quit">
|
||||
Would you really like to quit the application?
|
||||
</Entry>
|
||||
<Entry key="MessageBox_QuitTitle">
|
||||
Quit?
|
||||
</Entry>
|
||||
<Entry key="MessageBox_QuitError">
|
||||
The client failed to communicate the shutdown request to the runtime! Please try again...
|
||||
</Entry>
|
||||
<Entry key="MessageBox_QuitErrorTitle">
|
||||
Quit Error
|
||||
</Entry>
|
||||
<Entry key="MessageBox_SessionStartError">
|
||||
The application failed to start a new session. Please consult the application log for more information...
|
||||
</Entry>
|
||||
<Entry key="MessageBox_SessionStartErrorTitle">
|
||||
Session Start Error
|
||||
</Entry>
|
||||
<Entry key="MessageBox_SessionStopError">
|
||||
The application failed to properly stop the running session. Please consult the application log for more information...
|
||||
</Entry>
|
||||
<Entry key="MessageBox_SessionStopErrorTitle">
|
||||
Session Stop Error
|
||||
</Entry>
|
||||
<Entry key="MessageBox_ShutdownError">
|
||||
An unexpected error occurred during the shutdown procedure! Please consult the application log for more information...
|
||||
</Entry>
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||
using SafeExamBrowser.Contracts.Communication;
|
||||
|
@ -65,14 +64,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
|||
logger.Info("Initializing service session...");
|
||||
service.StartSession(session.Id, configuration.CurrentSettings);
|
||||
|
||||
try
|
||||
{
|
||||
sessionRunning = TryStartClient();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error("Failed to start client!", e);
|
||||
}
|
||||
sessionRunning = TryStartClient();
|
||||
|
||||
if (sessionRunning)
|
||||
{
|
||||
|
@ -96,14 +88,10 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
|||
logger.Info("Stopping service session...");
|
||||
service.StopSession(session.Id);
|
||||
|
||||
try
|
||||
if (!session.ClientProcess.HasTerminated)
|
||||
{
|
||||
StopClient();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error("Failed to terminate client!", e);
|
||||
}
|
||||
|
||||
sessionRunning = false;
|
||||
logger.Info($"Successfully stopped session with identifier '{session.Id}'.");
|
||||
|
@ -204,7 +192,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
|||
}
|
||||
else
|
||||
{
|
||||
logger.Warn("Attempting to kill client process since graceful shutdown failed!");
|
||||
logger.Warn("Attempting to kill client process since graceful termination failed!");
|
||||
KillClient();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,12 +75,12 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
|||
|
||||
if (initialized)
|
||||
{
|
||||
RegisterEvents();
|
||||
|
||||
logger.Info("--- Application successfully initialized ---");
|
||||
logger.Log(string.Empty);
|
||||
logger.Subscribe(runtimeWindow);
|
||||
|
||||
splashScreen.Hide();
|
||||
runtimeHost.ShutdownRequested += RuntimeHost_ShutdownRequested;
|
||||
|
||||
StartSession(true);
|
||||
}
|
||||
|
@ -88,6 +88,8 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
|||
{
|
||||
logger.Info("--- Application startup aborted! ---");
|
||||
logger.Log(string.Empty);
|
||||
|
||||
uiFactory.Show(TextKey.MessageBox_StartupError, TextKey.MessageBox_StartupErrorTitle, icon: MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
return initialized && sessionRunning;
|
||||
|
@ -95,8 +97,11 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
|||
|
||||
public void Terminate()
|
||||
{
|
||||
DeregisterEvents();
|
||||
|
||||
if (sessionRunning)
|
||||
{
|
||||
DeregisterSessionEvents();
|
||||
StopSession();
|
||||
}
|
||||
|
||||
|
@ -119,6 +124,8 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
|||
{
|
||||
logger.Info("--- Shutdown procedure failed! ---");
|
||||
logger.Log(string.Empty);
|
||||
|
||||
uiFactory.Show(TextKey.MessageBox_ShutdownError, TextKey.MessageBox_ShutdownErrorTitle, icon: MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
splashScreen?.Close();
|
||||
|
@ -127,13 +134,20 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
|||
private void StartSession(bool initial = false)
|
||||
{
|
||||
runtimeWindow.Show();
|
||||
logger.Info(">------ Initiating session procedure ------<");
|
||||
logger.Info(">>>--- Initiating session procedure ---<<<");
|
||||
|
||||
if (sessionRunning)
|
||||
{
|
||||
DeregisterSessionEvents();
|
||||
}
|
||||
|
||||
sessionRunning = initial ? sessionSequence.TryPerform() : sessionSequence.TryRepeat();
|
||||
|
||||
if (sessionRunning)
|
||||
{
|
||||
logger.Info(">------ Session is running ------<");
|
||||
RegisterSessionEvents();
|
||||
|
||||
logger.Info(">>>--- Session is running ---<<<");
|
||||
runtimeWindow.HideProgressBar();
|
||||
runtimeWindow.UpdateText(TextKey.RuntimeWindow_ApplicationRunning);
|
||||
|
||||
|
@ -144,7 +158,7 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
|||
}
|
||||
else
|
||||
{
|
||||
logger.Info(">------ Session procedure was aborted! ------<");
|
||||
logger.Info(">>>--- Session procedure was aborted! ---<<<");
|
||||
// TODO: Not when user chose to terminate after reconfiguration! Probably needs IOperationSequenceResult or alike...
|
||||
uiFactory.Show(TextKey.MessageBox_SessionStartError, TextKey.MessageBox_SessionStartErrorTitle, icon: MessageBoxIcon.Error);
|
||||
|
||||
|
@ -160,28 +174,65 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
|||
runtimeWindow.Show();
|
||||
runtimeWindow.BringToForeground();
|
||||
runtimeWindow.ShowProgressBar();
|
||||
logger.Info(">------ Reverting session operations ------<");
|
||||
logger.Info(">>>--- Reverting session operations ---<<<");
|
||||
|
||||
var success = sessionSequence.TryRevert();
|
||||
|
||||
if (success)
|
||||
{
|
||||
logger.Info(">------ Session is terminated ------<");
|
||||
logger.Info(">>>--- Session is terminated ---<<<");
|
||||
sessionRunning = false;
|
||||
|
||||
// TODO
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info(">------ Session reversion was erroneous! ------<");
|
||||
|
||||
// TODO
|
||||
logger.Info(">>>--- Session reversion was erroneous! ---<<<");
|
||||
uiFactory.Show(TextKey.MessageBox_SessionStopError, TextKey.MessageBox_SessionStopErrorTitle, icon: MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterEvents()
|
||||
{
|
||||
client.ConnectionLost += Client_ConnectionLost;
|
||||
runtimeHost.ShutdownRequested += RuntimeHost_ShutdownRequested;
|
||||
}
|
||||
|
||||
private void RegisterSessionEvents()
|
||||
{
|
||||
configuration.CurrentSession.ClientProcess.Terminated += ClientProcess_Terminated;
|
||||
}
|
||||
|
||||
private void DeregisterEvents()
|
||||
{
|
||||
client.ConnectionLost -= Client_ConnectionLost;
|
||||
runtimeHost.ShutdownRequested -= RuntimeHost_ShutdownRequested;
|
||||
}
|
||||
|
||||
private void DeregisterSessionEvents()
|
||||
{
|
||||
configuration.CurrentSession.ClientProcess.Terminated -= ClientProcess_Terminated;
|
||||
}
|
||||
|
||||
private void ClientProcess_Terminated(int exitCode)
|
||||
{
|
||||
logger.Error($"Client application has unexpectedly terminated with exit code {exitCode}!");
|
||||
// TODO: Check if message box is rendered on new desktop as well -> otherwise shutdown is blocked!
|
||||
uiFactory.Show(TextKey.MessageBox_ApplicationError, TextKey.MessageBox_ApplicationErrorTitle, icon: MessageBoxIcon.Error);
|
||||
|
||||
shutdown.Invoke();
|
||||
}
|
||||
|
||||
private void Client_ConnectionLost()
|
||||
{
|
||||
logger.Error("Lost connection to the client application!");
|
||||
// TODO: Check if message box is rendered on new desktop as well -> otherwise shutdown is blocked!
|
||||
uiFactory.Show(TextKey.MessageBox_ApplicationError, TextKey.MessageBox_ApplicationErrorTitle, icon: MessageBoxIcon.Error);
|
||||
|
||||
shutdown.Invoke();
|
||||
}
|
||||
|
||||
private void RuntimeHost_ShutdownRequested()
|
||||
{
|
||||
logger.Info("Received shutdown request from client application.");
|
||||
logger.Info("Received shutdown request from the client application.");
|
||||
shutdown.Invoke();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace SafeExamBrowser.Runtime.Communication
|
|||
{
|
||||
internal class RuntimeHost : BaseHost, IRuntimeHost
|
||||
{
|
||||
private bool allowConnection = true;
|
||||
private IConfigurationRepository configuration;
|
||||
|
||||
public Guid StartupToken { private get; set; }
|
||||
|
@ -33,7 +34,15 @@ namespace SafeExamBrowser.Runtime.Communication
|
|||
|
||||
protected override bool OnConnect(Guid? token = null)
|
||||
{
|
||||
return StartupToken == token;
|
||||
var authenticated = StartupToken == token;
|
||||
var accepted = allowConnection && authenticated;
|
||||
|
||||
if (accepted)
|
||||
{
|
||||
allowConnection = false;
|
||||
}
|
||||
|
||||
return accepted;
|
||||
}
|
||||
|
||||
protected override void OnDisconnect()
|
||||
|
@ -43,7 +52,6 @@ namespace SafeExamBrowser.Runtime.Communication
|
|||
|
||||
protected override Response OnReceive(Message message)
|
||||
{
|
||||
// TODO
|
||||
return new SimpleResponse(SimpleResponsePurport.UnknownMessage);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue