implement streamed commands

This commit is contained in:
zznty
2022-10-04 19:37:19 +07:00
parent 1e29719125
commit 39c3aa048d
3 changed files with 42 additions and 7 deletions

View File

@@ -1,3 +1,3 @@
namespace TorchRemote.Models.Requests; namespace TorchRemote.Models.Requests;
public record ChatCommandRequest(string Command); public record ChatCommandRequest(string Command, bool Streamed = false, TimeSpan? StreamingDuration = null);

View File

@@ -4,5 +4,5 @@ namespace TorchRemote.Plugin.Abstractions.Controllers;
public interface IChatController public interface IChatController
{ {
void SendMessage(ChatMessageRequest request); void SendMessage(ChatMessageRequest request);
Task<Guid> InvokeCommand(ChatCommandRequest request); Task InvokeCommand(ChatCommandRequest request);
} }

View File

@@ -1,5 +1,6 @@
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
using System.Text.Json;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using EmbedIO; using EmbedIO;
using EmbedIO.Routing; using EmbedIO.Routing;
@@ -83,7 +84,7 @@ public class ChatController : WebApiController, IChatController
} }
[Route(HttpVerbs.Post, $"{RootPath}/command")] [Route(HttpVerbs.Post, $"{RootPath}/command")]
public async Task<Guid> InvokeCommand([JsonData] ChatCommandRequest request) public async Task InvokeCommand([JsonData] ChatCommandRequest request)
{ {
if (Statics.CommandManager is null) if (Statics.CommandManager is null)
throw new HttpException(HttpStatusCode.ServiceUnavailable); throw new HttpException(HttpStatusCode.ServiceUnavailable);
@@ -94,12 +95,27 @@ public class ChatController : WebApiController, IChatController
var argsList = Regex.Matches(argText, "(\"[^\"]+\"|\\S+)").Cast<Match>().Select(x => x.ToString().Replace("\"", "")).ToList(); var argsList = Regex.Matches(argText, "(\"[^\"]+\"|\\S+)").Cast<Match>().Select(x => x.ToString().Replace("\"", "")).ToList();
var id = Guid.NewGuid(); var id = Guid.NewGuid();
var context = new WebSocketCommandContext(Statics.Torch, command.Plugin, argText, argsList, Statics.ChatModule, id);
if (await Statics.Torch.InvokeAsync(() => command.TryInvoke(context))) CommandContext context = request.Streamed ? new StreamedCommandContext(Statics.Torch, command.Plugin, argText, argsList, id) :
return id; new WebSocketCommandContext(Statics.Torch, command.Plugin, argText, argsList, Statics.ChatModule, id);
if (!await Statics.Torch.InvokeAsync(() => command.TryInvoke(context)))
throw HttpException.BadRequest("Invalid syntax", request.Command); throw HttpException.BadRequest("Invalid syntax", request.Command);
Response.StatusCode = 200;
Response.ContentType = "application/json";
if (request.Streamed)
{
await Task.Delay(request.StreamingDuration ?? TimeSpan.FromSeconds(15));
await JsonSerializer.SerializeAsync(Response.OutputStream, ((StreamedCommandContext)context).Answers, Statics.SerializerOptions);
}
else
{
await JsonSerializer.SerializeAsync(Response.OutputStream, id, Statics.SerializerOptions);
}
Response.Close();
} }
} }
@@ -118,3 +134,22 @@ internal class WebSocketCommandContext : CommandContext
_module.SendChatResponse(new ChatCommandResponse(_id, sender ?? Torch.Config.ChatName, message)); _module.SendChatResponse(new ChatCommandResponse(_id, sender ?? Torch.Config.ChatName, message));
} }
} }
internal class StreamedCommandContext : CommandContext
{
private readonly Guid _id;
private readonly List<ChatCommandResponse> _answers = new();
public IEnumerable<ChatCommandResponse> Answers => _answers;
public StreamedCommandContext(ITorchBase torch, ITorchPlugin plugin, string rawArgs, List<string> args, Guid id) : base(
torch, plugin, Sync.MyId, rawArgs, args)
{
_id = id;
}
public override void Respond(string message, string? sender = null, string? font = null)
{
_answers.Add(new ChatCommandResponse(_id, sender ?? Torch.Config.ChatName, message));
}
}