Moved logic related to command to MtRpcClient

This commit is contained in:
Viacheslav Demydiuk
2024-01-12 23:24:47 +02:00
parent 06082539c3
commit 4f9dc57c25
5 changed files with 165 additions and 143 deletions
+11 -11
View File
@@ -1,6 +1,6 @@
namespace MtClient
{
public enum MessageType
internal enum MessageType
{
Command = 0,
Response = 1,
@@ -11,12 +11,12 @@
Notification = 6
}
public enum MtNotificationType
internal enum MtNotificationType
{
ClientReady = 0
}
public abstract class MtMessage
internal abstract class MtMessage
{
public abstract MessageType MsgType { get; }
@@ -28,7 +28,7 @@
protected abstract string GetMessageBody();
}
public class MtCommand(int expertHandle, int commandType, int commandId, string payload) : MtMessage
internal class MtCommand(int expertHandle, int commandType, int commandId, string payload) : MtMessage
{
public override MessageType MsgType => MessageType.Command;
@@ -43,7 +43,7 @@
}
}
public class MtNotification(MtNotificationType notificationType) : MtMessage
internal class MtNotification(MtNotificationType notificationType) : MtMessage
{
public override MessageType MsgType => MessageType.Notification;
@@ -55,7 +55,7 @@
public MtNotificationType NotificationType { private set; get; } = notificationType;
}
public class MtEvent(int expertHandle, int eventType, string payload) : MtMessage
internal class MtEvent(int expertHandle, int eventType, string payload) : MtMessage
{
public override MessageType MsgType => MessageType.Event;
@@ -79,7 +79,7 @@
}
}
public class MtExpertAddedMsg(int expertHandle) : MtMessage
internal class MtExpertAddedMsg(int expertHandle) : MtMessage
{
public override MessageType MsgType => MessageType.ExpertAdded;
@@ -99,7 +99,7 @@
}
}
public class MtExpertRemovedMsg(int expertHandle) : MtMessage
internal class MtExpertRemovedMsg(int expertHandle) : MtMessage
{
public override MessageType MsgType => MessageType.ExpertRemoved;
@@ -119,7 +119,7 @@
}
}
public class MtExpertListMsg(HashSet<int> experts) : MtMessage
internal class MtExpertListMsg(HashSet<int> experts) : MtMessage
{
public override MessageType MsgType => MessageType.ExpertList;
@@ -145,7 +145,7 @@
}
}
public class MtResponse(int expertHandle, int commandId, string payload) : MtMessage
internal class MtResponse(int expertHandle, int commandId, string payload) : MtMessage
{
public override MessageType MsgType => MessageType.Response;
@@ -177,7 +177,7 @@
}
}
public static class MtMessageParser
internal static class MtMessageParser
{
static MtMessageParser()
{
+117 -4
View File
@@ -56,7 +56,35 @@ namespace MtClient
Log($"Disconnect: success");
}
public void Send(MtMessage message)
public string? SendCommand(int expertHandle, int commandType, string payload)
{
CommandTask commandTask = new();
int commandId;
lock (_tasks)
{
commandId = nextCommandId++;
_tasks[commandId] = commandTask;
}
MtCommand command = new(expertHandle, commandType, commandId, payload);
Send(command);
var response = commandTask.WaitResponse(10000); // 10 sec
lock (_tasks)
{
_tasks.Remove(commandId);
}
return response;
}
public void NotifyClientReady()
{
MtNotification notification = new(MtNotificationType.ClientReady);
Send(notification);
}
private void Send(MtMessage message)
{
lock (pendingMessages_)
{
@@ -164,8 +192,45 @@ namespace MtClient
Log("OnReceive: Failed parse message payload");
return;
}
MessageReceived?.Invoke(this, message);
switch (message.MsgType)
{
case MessageType.Event:
if (message is MtEvent e)
MtEventReceived?.Invoke(this, new(e.ExpertHandle, e.EventType, e.Payload));
break;
case MessageType.Response:
if (message is MtResponse response)
ProcessResponse(response);
break;
case MessageType.ExpertList:
if (message is MtExpertListMsg expertListMsg)
ExpertList?.Invoke(this, new(expertListMsg.Experts));
break;
case MessageType.ExpertAdded:
if (message is MtExpertAddedMsg expertAddedMsg)
ExpertAdded?.Invoke(this, new(expertAddedMsg.ExpertHandle));
break;
case MessageType.ExpertRemoved:
if (message is MtExpertRemovedMsg expertRemovedMsg)
ExpertRemoved?.Invoke(this, new(expertRemovedMsg.ExpertHandle));
break;
}
}
private void ProcessResponse(MtResponse msg)
{
var handle = msg.ExpertHandle;
var commandId = msg.CommandId;
var payload = msg.Payload;
Log($"ProcessResponse: {handle}, {commandId}, [{payload}]");
lock (_tasks)
{
if (_tasks.TryGetValue(commandId, out CommandTask? value))
value.SetResponse(payload);
}
}
private void Log(string msg)
@@ -173,9 +238,12 @@ namespace MtClient
Console.WriteLine($"[{Environment.CurrentManagedThreadId}] {msg}");
}
public event EventHandler<MtMessage>? MessageReceived;
public event EventHandler<EventArgs>? ConnectionFailed;
public event EventHandler<EventArgs>? Disconnected;
public event EventHandler<MtExpertListEventArgs>? ExpertList;
public event EventHandler<MtExpertEventArgs>? ExpertAdded;
public event EventHandler<MtExpertEventArgs>? ExpertRemoved;
public event EventHandler<MtEventArgs>? MtEventReceived;
private readonly ClientWebSocket ws_ = new();
private readonly string host_;
@@ -186,5 +254,50 @@ namespace MtClient
private readonly Thread receiveThread_;
private readonly Thread sendThread_;
private readonly EventWaitHandle sendWaiter_ = new AutoResetEvent(false);
private int nextCommandId = 0;
private readonly Dictionary<int, CommandTask> _tasks = [];
}
internal class CommandTask
{
private readonly EventWaitHandle responseWaiter_ = new AutoResetEvent(false);
private string? response_;
private readonly object locker_ = new();
public string? WaitResponse(int time)
{
responseWaiter_.WaitOne(time);
lock (locker_)
{
return response_;
}
}
public void SetResponse(string result)
{
lock (locker_)
{
response_ = result;
}
responseWaiter_.Set();
}
}
public class MtEventArgs(int expertHandle, int eventType, string payload) : EventArgs
{
public int ExpertHandle { get; } = expertHandle;
public int EventType { get; } = eventType;
public string Payload { get; } = payload;
}
public class MtExpertListEventArgs(HashSet<int> experts) : EventArgs
{
public HashSet<int> Experts { get; } = experts;
}
public class MtExpertEventArgs(int expert) : EventArgs
{
public int Expert { get; }= expert;
}
}