yavsc/src/cli/Commands/Streamer.cs

106 lines
4 KiB
C#
Raw Normal View History

2019-06-25 02:58:35 +01:00
using System;
using System.IO;
2019-06-24 14:30:47 +01:00
using System.Net.WebSockets;
2019-06-25 02:58:35 +01:00
using System.Threading;
using System.Threading.Tasks;
2020-10-18 23:00:17 +01:00
using System.Web;
2019-06-25 02:58:35 +01:00
using cli.Model;
using Microsoft.Extensions.CommandLineUtils;
2019-06-25 01:51:23 +01:00
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.OptionsModel;
2019-06-24 14:30:47 +01:00
2019-06-25 01:51:23 +01:00
namespace cli {
2019-06-25 17:11:16 +01:00
2020-12-29 13:02:31 +00:00
public class Streamer: ICommander {
2020-10-18 23:00:17 +01:00
private readonly ClientWebSocket _client;
private readonly ILogger _logger;
private readonly ConnectionSettings _cxSettings;
private readonly UserConnectionSettings _userCxSettings;
private CommandArgument _sourceArg;
private CommandArgument _destArg;
private CancellationTokenSource _tokenSource;
2020-12-29 13:02:31 +00:00
public Streamer(ILoggerFactory loggerFactory,
2020-10-18 23:00:17 +01:00
IOptions<ConnectionSettings> cxSettings,
IOptions<UserConnectionSettings> userCxSettings
)
{
_logger = loggerFactory.CreateLogger<Streamer>();
_cxSettings = cxSettings.Value;
_userCxSettings = userCxSettings.Value;
_client = new ClientWebSocket();
_client.Options.SetRequestHeader("Authorization", $"Bearer {_userCxSettings.AccessToken}");
}
public CommandLineApplication Integrate(CommandLineApplication rootApp)
{
CommandLineApplication streamCmd = rootApp.Command("nstream",
2020-10-18 23:00:17 +01:00
(target) =>
{
target.FullName = "Stream to server";
target.Description = "Stream arbitrary binary data to your server channel";
_sourceArg = target.Argument("source", "Source file to send, use '-' for standard input", false);
_destArg = target.Argument("destination", "destination file name", false);
target.HelpOption("-? | -h | --help");
});
streamCmd.OnExecute(async() => await DoExecute());
return streamCmd;
}
private async Task <int> DoExecute()
{
if (_sourceArg.Value != "-")
{
var fi = new FileInfo(_sourceArg.Value);
if (!fi.Exists) {
_logger.LogError("Input file doesn´t exist.");
return -2;
}
using (var stream = fi.OpenRead())
{
_logger.LogInformation("DoExecute from given file");
await DoStream(stream);
}
return 0;
}
else
{
using(var stream = Console.OpenStandardInput())
{
_logger.LogInformation("DoExecute from standard input");
await DoStream(stream);
}
return 0;
}
}
async Task DoStream (Stream stream)
{
_tokenSource = new CancellationTokenSource();
2020-12-29 19:42:37 +00:00
var url = _cxSettings.StreamingUrl + "/" + HttpUtility.UrlEncode(_destArg.Value);
2020-10-18 23:00:17 +01:00
_logger.LogInformation("Connecting to " + url);
await _client.ConnectAsync(new Uri(url), _tokenSource.Token);
_logger.LogInformation("Connected");
const int bufLen = Yavsc.Constants.WebSocketsMaxBufLen;
byte [] buffer = new byte[bufLen];
const int offset=0;
int read;
bool lastFrame;
WebSocketMessageType pckType = WebSocketMessageType.Binary;
do
{
read = await stream.ReadAsync(buffer, offset, bufLen);
lastFrame = read < Yavsc.Constants.WebSocketsMaxBufLen;
ArraySegment<byte> segment = new ArraySegment<byte>(buffer, offset, read);
await _client.SendAsync(segment, pckType, lastFrame, _tokenSource.Token);
2020-09-12 01:11:30 +01:00
_logger.LogInformation($"sent {segment.Count} ");
} while (!lastFrame);
_logger.LogInformation($"Closing socket");
await _client.CloseAsync(WebSocketCloseStatus.NormalClosure, "EOF", _tokenSource.Token);
2019-06-25 02:58:35 +01:00
}
2020-09-12 01:11:30 +01:00
}
2019-10-08 23:41:19 +01:00
}