New daemon communication code.

This commit is contained in:
Captain ALM 2021-03-23 18:07:47 +00:00
parent 7701457ac0
commit 12bcb4fe57
7 changed files with 361 additions and 270 deletions

View File

@ -197,7 +197,7 @@ public partial class MainWindow : Window
void StartupCheckMethod() void StartupCheckMethod()
{ {
ClientResponseState s = Client.SendDataMessage(DataMessage.Status); ClientResponseState s = GUISocketServer.SendDataMessage(DataMessage.Status);
Console.WriteLine(s); Console.WriteLine(s);
Application.Invoke(delegate Application.Invoke(delegate
{ {
@ -207,7 +207,7 @@ public partial class MainWindow : Window
void Refresh() void Refresh()
{ {
ClientResponseState s = Client.SendDataMessage(DataMessage.Status); ClientResponseState s = GUISocketServer.SendDataMessage(DataMessage.Status);
switch (s) switch (s)
{ {
case ClientResponseState.Error: case ClientResponseState.Error:
@ -364,7 +364,7 @@ public partial class MainWindow : Window
void OnStartClicked(object sender, EventArgs e) void OnStartClicked(object sender, EventArgs e)
{ {
ClientResponseState s = Client.SendDataMessage(DataMessage.Start); ClientResponseState s = GUISocketServer.SendDataMessage(DataMessage.Start);
switch (s) switch (s)
{ {
case ClientResponseState.Error: case ClientResponseState.Error:
@ -382,7 +382,7 @@ public partial class MainWindow : Window
void OnStopClicked(object sender, EventArgs e) void OnStopClicked(object sender, EventArgs e)
{ {
ClientResponseState s = Client.SendDataMessage(DataMessage.Stop); ClientResponseState s = GUISocketServer.SendDataMessage(DataMessage.Stop);
switch (s) switch (s)
{ {
case ClientResponseState.Error: case ClientResponseState.Error:
@ -417,7 +417,7 @@ public partial class MainWindow : Window
void RestartToggleBtn_Clicked(object sender, EventArgs e) void RestartToggleBtn_Clicked(object sender, EventArgs e)
{ {
ClientResponseState s = (RestartMode) ? Client.SendDataMessage(DataMessage.RestartOff) : Client.SendDataMessage(DataMessage.RestartOn); ClientResponseState s = (RestartMode) ? GUISocketServer.SendDataMessage(DataMessage.RestartOff) : GUISocketServer.SendDataMessage(DataMessage.RestartOn);
switch (s) switch (s)
{ {
case ClientResponseState.Error: case ClientResponseState.Error:

View File

@ -7,7 +7,9 @@ namespace MelonVPNConnectedClientUpdate
{ {
public static void Main(string[] args) public static void Main(string[] args)
{ {
Client.SendCustomMessage(Messages.GetClientListMessage(Console.ReadLine())); GUISocketServer.oneConnect();
GUISocketServer.SendCustomMessage(Messages.GetClientListMessage(Console.ReadLine()));
GUISocketServer.oneDispose();
} }
} }
} }

View File

@ -1,41 +0,0 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace MelonVPNCore
{
public static class Client
{
public static ClientResponseState SendDataMessage(DataMessage msg) => SendDataMessage(msg, false);
public static ClientResponseState SendDataMessage(DataMessage msg, bool IsSendingFromDaemon) => SendCustomMessage(Messages.GetMessage(msg), IsSendingFromDaemon);
public static ClientResponseState SendCustomMessage(string msg) => SendCustomMessage(msg, false);
public static ClientResponseState SendCustomMessage(string msg, bool IsSendingFromDaemon)
{
IPHostEntry host = Dns.GetHostEntry("localhost");
IPAddress ipAddress = host.AddressList[0];
IPEndPoint remoteEndPoint = new IPEndPoint(ipAddress, IsSendingFromDaemon ? 22036 : 22035);
try
{
if (msg == Messages.EOF || msg == "") return ClientResponseState.Blank;
Socket client = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
client.Connect(remoteEndPoint);
client.ReceiveTimeout = 5000;
client.SendTimeout = 5000;
byte[] bytes = Encoding.ASCII.GetBytes(msg);
client.Send(bytes);
client.Close();
return ClientResponseState.Sent;
}
catch (Exception e)
{
Console.WriteLine(e);
return ClientResponseState.Error;
}
}
}
}

View File

@ -3,23 +3,32 @@ using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Collections.Generic;
namespace MelonVPNCore namespace MelonVPNCore
{ {
public class DaemonClient : IDisposable public class DaemonClient : IDisposable
{ {
public ClientResponseState SendDataMessage(DataMessage msg) => SendCustomMessage(msg); public ClientResponseState SendDataMessage(DataMessage msg) => SendCustomMessage(Messages.GetMessage(msg));
public ClientResponseState SendCustomMessage(DataMessage msg) => SendCustomMessage(Messages.GetMessage(msg)));
private Socket _sock; private Socket _sock;
public static int timeout = 5000; public static int timeout = 5000;
private Thread _recvThread; private Thread _recvThread;
private bool _stayConnected = false; private bool _stayConnected = false;
public event EventHandler<String> messageReceived; public event EventHandler<String> messageReceived;
public event EventHandler<Exception> connectionError;
public DaemonClient() public DaemonClient() { }
public DaemonClient(Socket sockIn)
{
if (sockIn is null) throw new ArgumentNullException(nameof(sockIn));
}
public void start()
{ {
try try
{
if (_sock is null)
{ {
IPHostEntry host = Dns.GetHostEntry("localhost"); IPHostEntry host = Dns.GetHostEntry("localhost");
IPAddress ipAddress = host.AddressList[0]; IPAddress ipAddress = host.AddressList[0];
@ -27,6 +36,11 @@ namespace MelonVPNCore
_sock = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); _sock = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
_stayConnected = true; _stayConnected = true;
_sock.Connect(remoteEndPoint); _sock.Connect(remoteEndPoint);
}
else
{
_stayConnected = true;
}
_sock.ReceiveTimeout = timeout; _sock.ReceiveTimeout = timeout;
_sock.SendTimeout = timeout; _sock.SendTimeout = timeout;
_recvThread = new Thread(recvThreader) _recvThread = new Thread(recvThreader)
@ -34,12 +48,13 @@ namespace MelonVPNCore
IsBackground = true IsBackground = true
}; };
_recvThread.Start(); _recvThread.Start();
} catch (Exception e) }
catch (Exception e)
{ {
_stayConnected = false; _stayConnected = false;
Console.WriteLine(e); Console.WriteLine(e);
_sock = null; _sock = null;
if (! (_recvThread is null)) if (!(_recvThread is null))
{ {
if (_recvThread.IsAlive) _recvThread.Abort(); if (_recvThread.IsAlive) _recvThread.Abort();
_recvThread = null; _recvThread = null;
@ -48,11 +63,6 @@ namespace MelonVPNCore
} }
} }
public DaemonClient(Socket sockIn)
{
if (sockIn is null) throw new InvalidOperationException("Passed Socket is Null.");
}
public ClientResponseState SendCustomMessage(string msg) public ClientResponseState SendCustomMessage(string msg)
{ {
try try
@ -65,6 +75,7 @@ namespace MelonVPNCore
catch (Exception e) catch (Exception e)
{ {
Console.WriteLine(e); Console.WriteLine(e);
connectionError?.Invoke(this, e);
return ClientResponseState.Error; return ClientResponseState.Error;
} }
} }
@ -85,8 +96,11 @@ namespace MelonVPNCore
data += Encoding.ASCII.GetString(bytes, 0, bytesRec); data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (data.IndexOf(Messages.EOF, StringComparison.CurrentCulture) > -1) break; if (data.IndexOf(Messages.EOF, StringComparison.CurrentCulture) > -1) break;
} }
messageReceived?.Invoke(this, data);
messageReceived?.Invoke(null, data); } catch (SocketException e)
{
Console.WriteLine(e);
connectionError?.Invoke(this, e);
} catch (Exception e) } catch (Exception e)
{ {
Console.WriteLine(e); Console.WriteLine(e);
@ -104,7 +118,13 @@ namespace MelonVPNCore
if (disposing) if (disposing)
{ {
_stayConnected = false; _stayConnected = false;
try
{
_sock.Shutdown(SocketShutdown.Both); _sock.Shutdown(SocketShutdown.Both);
} catch (SocketException e)
{
Console.WriteLine(e);
}
if (!(_recvThread is null)) if (!(_recvThread is null))
{ {
if (_recvThread.IsAlive) _recvThread.Abort(); if (_recvThread.IsAlive) _recvThread.Abort();
@ -135,7 +155,7 @@ namespace MelonVPNCore
private bool _stayListening = false; private bool _stayListening = false;
public event EventHandler<DaemonClient> clientConnected; public event EventHandler<DaemonClient> clientConnected;
public DaemonServer() public void start()
{ {
try try
{ {
@ -151,7 +171,8 @@ namespace MelonVPNCore
IsBackground = true IsBackground = true
}; };
_lThread.Start(); _lThread.Start();
} catch (Exception e) }
catch (Exception e)
{ {
_stayListening = false; _stayListening = false;
Console.WriteLine(e); Console.WriteLine(e);
@ -171,9 +192,8 @@ namespace MelonVPNCore
{ {
try try
{ {
Socket handled = _sock.Accept(); DaemonClient dc = new DaemonClient(_sock.Accept());
DaemonClient dc = new DaemonClient(handled); clientConnected?.Invoke(this,dc);
clientConnected?.Invoke(null,dc);
} }
catch (Exception e) catch (Exception e)
{ {
@ -214,4 +234,96 @@ namespace MelonVPNCore
#endregion #endregion
} }
public class DaemonClientMultiplexor : IDisposable
{
public ClientResponseState SendDataMessage(DataMessage msg) => SendCustomMessage(Messages.GetMessage(msg));
private List<DaemonClient> plexed = new List<DaemonClient>();
private object slockplexed = new object();
private object slockcon = new object();
private object slockrecv = new object();
public event EventHandler<String> clientMessageReceived;
public event EventHandler<DaemonClient> clientConnectComplete;
public bool startClients = true;
public bool disconnectErroredClients = true;
public DaemonClientMultiplexor(DaemonServer dsIn)
{
if (dsIn is null) throw new ArgumentNullException(nameof(dsIn));
dsIn.clientConnected += DsIn_ClientConnected;
}
void DsIn_ClientConnected(object sender, DaemonClient e)
{
lock (slockplexed) plexed.Add(e);
e.messageReceived += E_MessageReceived;
e.connectionError += E_ConnectionError;
if (startClients) e.start();
lock(slockcon) clientConnectComplete?.Invoke(this, e);
}
void E_MessageReceived(object sender, string e)
{
lock(slockrecv) clientMessageReceived?.Invoke(this, e);
}
void E_ConnectionError(object sender, Exception e)
{
if(disconnectErroredClients) ((DaemonClient)sender).Dispose();
}
public ClientResponseState SendCustomMessage(string msg)
{
var toret = ClientResponseState.Sent;
lock (slockplexed) {
foreach (DaemonClient c in plexed)
{
try
{
if (c.SendCustomMessage(msg) != ClientResponseState.Sent) toret = ClientResponseState.Error;
} catch (Exception e)
{
Console.WriteLine(e);
}
}
}
return toret;
}
public void disconnectAllClients()
{
lock (slockplexed) foreach (DaemonClient c in plexed) c.Dispose();
lock (slockplexed) plexed.Clear();
}
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
lock(slockplexed) foreach (DaemonClient c in plexed) c.Dispose();
lock (slockplexed) plexed.Clear();
}
plexed = null;
slockcon = null;
slockrecv = null;
slockplexed = null;
disposedValue = true;
}
}
// This code added to correctly implement the disposable pattern.
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
}
#endregion
}
} }

View File

@ -15,50 +15,55 @@ namespace MelonVPNCore
private static bool isRestarting = false; private static bool isRestarting = false;
private static int startingTime = 3000; private static int startingTime = 3000;
private static int restartDelay = 250; private static int restartDelay = 250;
private static DaemonServer _srv;
private static DaemonClientMultiplexor _mlt;
private static string lastClientUpdate = Messages.EOF;
public static void StartServer() public static void StartServer()
{ {
IPHostEntry host = Dns.GetHostEntry("localhost"); _srv = new DaemonServer();
IPAddress ipAddress = host.AddressList[0]; _mlt = new DaemonClientMultiplexor(_srv);
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 22035); _mlt.clientMessageReceived += clientMessageReceived;
_srv.start();
try
{
Socket listener = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(localEndPoint);
listener.Listen(32);
string lastClientUpdate = Messages.EOF;
while (true)
{
Socket handler = listener.Accept();
string data = null;
byte[] bytes = null;
while (true)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (data.IndexOf(Messages.EOF, StringComparison.CurrentCulture) > -1) break;
} }
public static bool isProcessOnline(Process p)
{
if (p == null)
{
return false;
}
else
{
if (p.HasExited)
{
return false;
}
else
{
return true;
}
}
}
static void clientMessageReceived(object sender, string data)
{
try
{
if (data.StartsWith(Messages.ClientListStartMsg, StringComparison.CurrentCulture) && shouldBeRunning) if (data.StartsWith(Messages.ClientListStartMsg, StringComparison.CurrentCulture) && shouldBeRunning)
{ {
lastClientUpdate = data; lastClientUpdate = data;
Client.SendCustomMessage(lastClientUpdate, true); _mlt.SendCustomMessage(lastClientUpdate);
} }
else if (data == Messages.RestartOnMsg) else if (data == Messages.RestartOnMsg)
{ {
shouldRestart = true; shouldRestart = true;
Client.SendDataMessage(DataMessage.RestartOn, true); _mlt.SendDataMessage(DataMessage.RestartOn);
} }
else if (data == Messages.RestartOffMsg) else if (data == Messages.RestartOffMsg)
{ {
shouldRestart = false; shouldRestart = false;
Client.SendDataMessage(DataMessage.RestartOff, true); _mlt.SendDataMessage(DataMessage.RestartOff);
} }
else if (data == Messages.StatusMsg) else if (data == Messages.StatusMsg)
{ {
@ -68,27 +73,27 @@ namespace MelonVPNCore
if (isRestarting) if (isRestarting)
{ {
Console.WriteLine("Sending response: restarting"); Console.WriteLine("Sending response: restarting");
Client.SendDataMessage(DataMessage.Restarting, true); _mlt.SendDataMessage(DataMessage.Restarting);
Client.SendCustomMessage(lastClientUpdate, true); _mlt.SendCustomMessage(lastClientUpdate);
} }
else else
{ {
Console.WriteLine("Sending response: online"); Console.WriteLine("Sending response: online");
Client.SendDataMessage(DataMessage.Online, true); _mlt.SendDataMessage(DataMessage.Online);
Client.SendCustomMessage(lastClientUpdate, true); _mlt.SendCustomMessage(lastClientUpdate);
} }
} }
else else
{ {
Console.WriteLine("Sending response: offline"); Console.WriteLine("Sending response: offline");
Client.SendDataMessage(DataMessage.Offline, true); _mlt.SendDataMessage(DataMessage.Offline);
Client.SendCustomMessage(Messages.ClientListEmptyMsg, true); _mlt.SendCustomMessage(Messages.ClientListEmptyMsg);
} }
Client.SendDataMessage((shouldRestart) ? DataMessage.RestartOn : DataMessage.RestartOff); _mlt.SendDataMessage((shouldRestart) ? DataMessage.RestartOn : DataMessage.RestartOff);
} }
else if (data == Messages.StartMsg) else if (data == Messages.StartMsg)
{ {
if (! isProcessOnline(currentVpnProcess)) if (!isProcessOnline(currentVpnProcess))
{ {
shouldBeRunning = true; shouldBeRunning = true;
Console.WriteLine("Starting VPN"); Console.WriteLine("Starting VPN");
@ -96,11 +101,11 @@ namespace MelonVPNCore
{ {
Console.WriteLine("Starting embedded process"); Console.WriteLine("Starting embedded process");
Console.WriteLine("Sending starting reply"); Console.WriteLine("Sending starting reply");
Client.SendDataMessage(DataMessage.Starting, true); _mlt.SendDataMessage(DataMessage.Starting);
if (StartEProcess(true)) if (StartEProcess(true))
{ {
Console.WriteLine("Sending online reply"); Console.WriteLine("Sending online reply");
Client.SendDataMessage(DataMessage.Online, true); _mlt.SendDataMessage(DataMessage.Online);
currentVpnProcess.EnableRaisingEvents = true; currentVpnProcess.EnableRaisingEvents = true;
} }
else { throw new InvalidOperationException("Client crashed!"); } else { throw new InvalidOperationException("Client crashed!"); }
@ -112,8 +117,8 @@ namespace MelonVPNCore
Console.WriteLine("It looked like this: " + e); Console.WriteLine("It looked like this: " + e);
currentVpnProcess.Dispose(); currentVpnProcess.Dispose();
currentVpnProcess = null; currentVpnProcess = null;
Client.SendDataMessage(DataMessage.Error, true); _mlt.SendDataMessage(DataMessage.Error);
Client.SendCustomMessage(Messages.ClientListEmptyMsg, true); _mlt.SendCustomMessage(Messages.ClientListEmptyMsg);
} }
} }
else else
@ -140,8 +145,8 @@ namespace MelonVPNCore
Console.WriteLine("There was an error. But I fixed it."); Console.WriteLine("There was an error. But I fixed it.");
Console.WriteLine("It looked like this: " + e); Console.WriteLine("It looked like this: " + e);
currentVpnProcess = null; currentVpnProcess = null;
Client.SendDataMessage(DataMessage.Error, true); _mlt.SendDataMessage(DataMessage.Error);
Client.SendCustomMessage(Messages.ClientListEmptyMsg, true); _mlt.SendCustomMessage(Messages.ClientListEmptyMsg);
haderr = true; haderr = true;
} }
} }
@ -152,16 +157,13 @@ namespace MelonVPNCore
if (!haderr) if (!haderr)
{ {
Console.WriteLine("Sending offline reply"); Console.WriteLine("Sending offline reply");
Client.SendDataMessage(DataMessage.Offline, true); _mlt.SendDataMessage(DataMessage.Offline);
Client.SendCustomMessage(Messages.ClientListEmptyMsg, true); _mlt.SendCustomMessage(Messages.ClientListEmptyMsg);
} }
} }
Client.SendDataMessage(DataMessage.Blank, true); _mlt.SendDataMessage(DataMessage.Blank);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
} }
catch (Exception e) catch (Exception e)
{ {
@ -169,24 +171,6 @@ namespace MelonVPNCore
} }
} }
public static bool isProcessOnline(Process p)
{
if (p == null)
{
return false;
}
else
{
if (p.HasExited)
{
return false;
}
else
{
return true;
}
}
}
static void CurrentVpnProcess_Exited(object sender, EventArgs e) static void CurrentVpnProcess_Exited(object sender, EventArgs e)
{ {
@ -199,11 +183,11 @@ namespace MelonVPNCore
while (shouldRestart && shouldBeRunning) while (shouldRestart && shouldBeRunning)
{ {
Console.WriteLine("Sending restarting reply"); Console.WriteLine("Sending restarting reply");
Client.SendDataMessage(DataMessage.Restarting, true); _mlt.SendDataMessage(DataMessage.Restarting);
if (StartEProcess(false)) if (StartEProcess(false))
{ {
Console.WriteLine("Sending online reply"); Console.WriteLine("Sending online reply");
Client.SendDataMessage(DataMessage.Online, true); _mlt.SendDataMessage(DataMessage.Online);
currentVpnProcess.EnableRaisingEvents = true; currentVpnProcess.EnableRaisingEvents = true;
imonline = true; imonline = true;
break; break;
@ -220,8 +204,8 @@ namespace MelonVPNCore
{ {
shouldBeRunning = false; shouldBeRunning = false;
Console.WriteLine("Sending offline reply"); Console.WriteLine("Sending offline reply");
Client.SendDataMessage(DataMessage.Offline, true); _mlt.SendDataMessage(DataMessage.Offline);
Client.SendCustomMessage(Messages.ClientListEmptyMsg, true); _mlt.SendCustomMessage(Messages.ClientListEmptyMsg);
} }
} }

View File

@ -2,41 +2,76 @@
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
using System.Threading;
namespace MelonVPNCore namespace MelonVPNCore
{ {
public static class GUISocketServer public static class GUISocketServer
{ {
public static ClientResponseState SendDataMessage(DataMessage msg) => SendCustomMessage(Messages.GetMessage(msg));
public static int reconnectTimeout = 2000;
public static DaemonClient client;
public static event EventHandler<ClientResponseState> Receive; public static event EventHandler<ClientResponseState> Receive;
public static event EventHandler<ConnectedClient[]> ClientListUpdate; public static event EventHandler<ConnectedClient[]> ClientListUpdate;
private static bool waitfcl = false;
private static bool exec = true;
public static void StartServer() public static void StartServer()
{ {
IPHostEntry host = Dns.GetHostEntry("localhost");
IPAddress ipAddress = host.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 22036);
while (exec)
{
try try
{ {
Socket listener = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); client = new DaemonClient();
listener.Bind(localEndPoint); client.connectionError += Client_ConnectionError;
listener.Listen(32); client.messageReceived += Client_MessageReceived;
waitfcl = true;
while (true) client.start();
while (waitfcl) Thread.Sleep(reconnectTimeout);
client.connectionError -= Client_ConnectionError;
client.messageReceived -= Client_MessageReceived;
client.Dispose();
}
catch (InvalidOperationException e)
{ {
Socket handler = listener.Accept(); Console.WriteLine(e);
}
string data = ""; Thread.Sleep(reconnectTimeout);
byte[] bytes = null; }
Console.WriteLine("GUISocketServer has reached the end.");
while (true)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (data.IndexOf(Messages.EOF, StringComparison.CurrentCulture) > -1) break;
} }
public static void oneConnect()
{
try
{
client = new DaemonClient();
client.messageReceived += Client_MessageReceived;
waitfcl = true;
client.start();
}
catch (InvalidOperationException e)
{
Console.WriteLine(e);
}
}
public static void oneDispose()
{
client.messageReceived -= Client_MessageReceived;
client.Dispose();
}
static void Client_ConnectionError(object sender, Exception e)
{
waitfcl = false;
}
static void Client_MessageReceived(object sender, string data)
{
try
{
ClientResponseState ret = ClientResponseState.None; ClientResponseState ret = ClientResponseState.None;
if (data == Messages.OnlineMsg) ret = ClientResponseState.Online; if (data == Messages.OnlineMsg) ret = ClientResponseState.Online;
if (data == Messages.OfflineMsg) ret = ClientResponseState.Offline; if (data == Messages.OfflineMsg) ret = ClientResponseState.Offline;
@ -54,18 +89,18 @@ namespace MelonVPNCore
ConnectedClient[] clients = ClientListParser.Parse(jsonData); ConnectedClient[] clients = ClientListParser.Parse(jsonData);
ClientListUpdate?.Invoke(null, clients); ClientListUpdate?.Invoke(null, clients);
} }
handler.Shutdown(SocketShutdown.Both);
handler.Close();
Receive?.Invoke(null, ret); Receive?.Invoke(null, ret);
} }
}
catch (Exception e) catch (Exception e)
{ {
Console.WriteLine(e); Console.WriteLine(e);
} }
Console.WriteLine("GUI socket server reached the end"); }
public static ClientResponseState SendCustomMessage(string msg)
{
var toret = client?.SendCustomMessage(msg);
return (toret.HasValue) ? toret.Value : ClientResponseState.Error;
} }
} }
} }

View File

@ -29,7 +29,6 @@
<Compile Include="DaemonSocketServer.cs" /> <Compile Include="DaemonSocketServer.cs" />
<Compile Include="ThreadWrapper.cs" /> <Compile Include="ThreadWrapper.cs" />
<Compile Include="Messages.cs" /> <Compile Include="Messages.cs" />
<Compile Include="Client.cs" />
<Compile Include="DataMessage.cs" /> <Compile Include="DataMessage.cs" />
<Compile Include="ClientResponseState.cs" /> <Compile Include="ClientResponseState.cs" />
<Compile Include="GUISocketServer.cs" /> <Compile Include="GUISocketServer.cs" />