119 lines
5.2 KiB
C#
119 lines
5.2 KiB
C#
using CommandLine;
|
|
using StackExchange.Redis;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using RedisManager.Utils;
|
|
|
|
namespace RedisManager.Commands
|
|
{
|
|
/// <summary>
|
|
/// Contains command line options and implementations for Redis Pub/Sub operations.
|
|
/// Provides functionality for PUBLISH, SUBSCRIBE, and UNSUBSCRIBE commands.
|
|
/// </summary>
|
|
[Verb("publish", HelpText = "Publish a message to a channel.")]
|
|
public class PublishOptions
|
|
{
|
|
[Option('i', "instance", Required = true, HelpText = "Instance name.")]
|
|
public string Instance { get; set; }
|
|
[Value(0, MetaName = "channel", Required = true, HelpText = "Channel name.")]
|
|
public string Channel { get; set; }
|
|
[Value(1, MetaName = "message", Required = true, HelpText = "Message to publish.")]
|
|
public string Message { get; set; }
|
|
[Option("table", Required = false, HelpText = "Output as table.")]
|
|
public bool Table { get; set; }
|
|
}
|
|
|
|
[Verb("subscribe", HelpText = "Subscribe to one or more channels.")]
|
|
public class SubscribeOptions
|
|
{
|
|
[Option('i', "instance", Required = true, HelpText = "Instance name.")]
|
|
public string Instance { get; set; }
|
|
[Value(0, MetaName = "channels", Min = 1, Required = true, HelpText = "Channels to subscribe to.")]
|
|
public IEnumerable<string> Channels { get; set; }
|
|
}
|
|
|
|
[Verb("unsubscribe", HelpText = "Unsubscribe from one or more channels.")]
|
|
public class UnsubscribeOptions
|
|
{
|
|
[Option('i', "instance", Required = true, HelpText = "Instance name.")]
|
|
public string Instance { get; set; }
|
|
[Value(0, MetaName = "channels", Min = 1, Required = true, HelpText = "Channels to unsubscribe from.")]
|
|
public IEnumerable<string> Channels { get; set; }
|
|
}
|
|
|
|
public static class PubSubCommands
|
|
{
|
|
/// <summary>
|
|
/// Executes the PUBLISH command to publish a message to a channel.
|
|
/// </summary>
|
|
/// <param name="opts">The PublishOptions containing instance, channel, and message.</param>
|
|
/// <param name="config">The RedisManager configuration.</param>
|
|
/// <returns>Exit code (0 for success, non-zero for failure).</returns>
|
|
public static int RunPublish(PublishOptions opts, Config config)
|
|
{
|
|
var instance = RedisUtils.GetInstance(config, opts.Instance);
|
|
using var redis = RedisUtils.ConnectRedis(instance);
|
|
var sub = redis.GetSubscriber();
|
|
var count = sub.Publish(opts.Channel, opts.Message);
|
|
if (opts.Table)
|
|
RedisUtils.PrintTable(new[] { "Channel", "Receivers" }, new List<string[]> { new[] { opts.Channel, count.ToString() } });
|
|
else
|
|
Console.WriteLine(Output.Green($"Published to {opts.Channel}, receivers: {count}"));
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Executes the SUBSCRIBE command to subscribe to one or more channels.
|
|
/// </summary>
|
|
/// <param name="opts">The SubscribeOptions containing instance and channels.</param>
|
|
/// <param name="config">The RedisManager configuration.</param>
|
|
/// <returns>Exit code (0 for success, non-zero for failure).</returns>
|
|
public static int RunSubscribe(SubscribeOptions opts, Config config)
|
|
{
|
|
var instance = RedisUtils.GetInstance(config, opts.Instance);
|
|
using var redis = RedisUtils.ConnectRedis(instance);
|
|
var sub = redis.GetSubscriber();
|
|
var channels = opts.Channels;
|
|
Console.WriteLine(Output.Yellow($"Subscribed to: {string.Join(", ", channels)}. Press Ctrl+C to exit."));
|
|
using var cts = new CancellationTokenSource();
|
|
Console.CancelKeyPress += (s, e) => { e.Cancel = true; cts.Cancel(); };
|
|
foreach (var channel in channels)
|
|
{
|
|
sub.Subscribe(channel, (ch, msg) =>
|
|
{
|
|
Console.WriteLine(Output.Cyan($"[{ch}] {msg}"));
|
|
});
|
|
}
|
|
try
|
|
{
|
|
while (!cts.IsCancellationRequested)
|
|
{
|
|
Thread.Sleep(100);
|
|
}
|
|
}
|
|
catch (OperationCanceledException) { }
|
|
Console.WriteLine(Output.Yellow("Unsubscribed and exiting."));
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Executes the UNSUBSCRIBE command to unsubscribe from one or more channels.
|
|
/// </summary>
|
|
/// <param name="opts">The UnsubscribeOptions containing instance and channels.</param>
|
|
/// <param name="config">The RedisManager configuration.</param>
|
|
/// <returns>Exit code (0 for success, non-zero for failure).</returns>
|
|
public static int RunUnsubscribe(UnsubscribeOptions opts, Config config)
|
|
{
|
|
var instance = RedisUtils.GetInstance(config, opts.Instance);
|
|
using var redis = RedisUtils.ConnectRedis(instance);
|
|
var sub = redis.GetSubscriber();
|
|
foreach (var channel in opts.Channels)
|
|
{
|
|
sub.Unsubscribe(channel);
|
|
Console.WriteLine(Output.Yellow($"Unsubscribed from {channel}"));
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
} |