从 Sentinel C# 获取 Redis Master 地址

Getting Redis Master address from Sentinel C#

我正在尝试使用 sentinel 获取我的 master 的连接地址,问题是 sentinel 仅在故障转移时发送地址,但是如果我的 master 已关闭并且 slave 被提升为 master 而我的应用程序是刚刚启动它不会知道也不会收到原来的主人挂了的消息,有没有办法和哨兵沟通并问他他认为主人是谁使用C# servicestack redis客户端?

不得不以艰难的方式做到这一点,我使用下一个代码片段模仿 redis-cli 命令:(剩下的就是解析响应的结果)

   public string GetMasterFromSentinel(string sentinelAddress)
    {
        TcpClient server;

        try
        {
            var splittedAddress = sentinelAddress.Split(':');
            server = new TcpClient(splittedAddress[0], splittedAddress[1].ParseInt());
        }
        catch (SocketException)
        {
            _log.Error("Unable to connect to server");
            return string.Empty;
        }
        NetworkStream ns = server.GetStream();
        var payload = new byte[] { 0x2a, 0x32, 0x0d, 0x0a, 0x24, 0x38, 0x0d, 0x0a, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x65, 0x6c, 
                0x0d, 0x0a, 0x24, 0x37, 0x0d, 0x0a, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x73, 0x0d, 0x0a };
        ns.Write(payload, 0, payload.Length);
        ns.Flush();
        var data = new byte[1024];
        ns.Read(data, 0, data.Length);
        var recv = ns.Read(data, 0, data.Length);

        ns.Close();
        server.Close();
        return ParseResponse(data);
    }

我已经写了一些测试代码来获取主机的 IP 和端口 --- 通过 IP 和端口(从机或主机将工作)哨兵。 此代码使用来自 StackExchange.Redis

的 NuGet 包
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Test
{
    public class Sentinel
    {
        private ConnectionMultiplexer Conn { get; }
        private IServer Server { get; }
        protected StringWriter ConnectionLog { get; }

        public Sentinel()
        {
            var options = new ConfigurationOptions()
            {
                CommandMap = CommandMap.Sentinel,
                EndPoints = { { "192.168.1.64", 26379 } },  //IP and Port of Sentinel
                AllowAdmin = true,
                TieBreaker = "",
                SyncTimeout = 5000
            };
            Conn = ConnectionMultiplexer.Connect(options, ConnectionLog);
            Server = Conn.GetServer("192.168.1.64", 26379); //IP and Port of Sentinel
        }

        public void SentinelGetMasterAddressByNameTest(string nameOfMaster)
        {
            var endpoint = Server.SentinelGetMasterAddressByName(nameOfMaster); 
            var ipEndPoint = endpoint as IPEndPoint;
            Console.WriteLine("The Master's <IP:Port>: {0}:{1}", ipEndPoint.Address, ipEndPoint.Port);
        }
    }



    class Program
    {

        static void Main(string[] args)
        {
           var sentinel = new Sentinel();
           sentinel.SentinelGetMasterAddressByNameTest("redis-test"); //Passing name of the master
           Console.ReadLine();
        }
    }
}