Search code examples
c#asp.net-coresignalrmsgpacksignalr-backplane

How to deserialize SignalR messages from Redis backplane


I need to read published messages by SignalR from Redis backplane. But they have strange format for me. Example:

"\x92\x90\x81\xa4json\xc4\x83{\"type\":1,\"target\":\"ReceiveGroupMessage\",\"arguments\":[{\"senderId\":null,\"message\":\"hello\",\"sentAt\":\"2023-07-22T16:48:08.7001126Z\"}]}\x1e"

Most of content is JSON, but what about start and the end? What is this, what it means and how can I deserialize it?

I tried:

var result = MessagePackSerializer.Deserialize<object>(value);

where value is RedisValue from subscription callback. But it results with:result

so I don't know how can I extract the value from json key.

That's whole code:

public class RedisSaveMessageBackgroundService : BackgroundService
{
    private readonly IConfiguration _configuration;
    private readonly IConnectionMultiplexer _connectionMultiplexer;

    public RedisSaveMessageBackgroundService(IConfiguration configuration,
        IConnectionMultiplexer connectionMultiplexer)
    {
        _configuration = configuration;
        _connectionMultiplexer = connectionMultiplexer;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        using (var connection = new NpgsqlConnection(_configuration.GetConnectionString("YugabyteDB")))
        {
            connection.Open();

            static async void Handler(RedisChannel channel, RedisValue value)
            {
                if (value == default)
                    return;

                var message = ReadMessage(value);
                await connection.ExecuteAsync(SQL_INSERT); // details omitted
            }

            var subscriber = _connectionMultiplexer.GetSubscriber();
            await subscriber.SubscribeAsync(new RedisChannel("*SignalRHub.MessagingHub:user:*", RedisChannel.PatternMode.Pattern), Handler);
            await subscriber.SubscribeAsync(new RedisChannel("*SignalRHub.MessagingHub:group:*", RedisChannel.PatternMode.Pattern), Handler);
        }

        await Task.Delay(Timeout.Infinite, stoppingToken);
    }

    private static Message ReadMessage(RedisValue value)
    {
        // What here
        throw new NotImplementedException();
    }
}

Solution

  • Please try to use below code.

        public IActionResult testmsg()
        {
            string input = "\x92\x90\x81\xa4json\xc4\x83{\"type\":1,\"target\":\"ReceiveGroupMessage\",\"arguments\":[{\"senderId\":null,\"message\":\"hello\",\"sentAt\":\"2023-07-22T16:48:08.7001126Z\"}]}\x1e";
    
            // Step 1: Remove the unwanted characters
            int startIndex = input.IndexOf('{'); // Find the starting index of the JSON part
            int endIndex = input.LastIndexOf('}'); // Find the ending index of the JSON part
            string jsonPart = input.Substring(startIndex, endIndex - startIndex + 1); // Extract the JSON part
    
            // Step 2: Convert the JSON to a C# object
            var result = JsonConvert.DeserializeObject<CustomMessage>(jsonPart);
    
            return Ok(result);
        }
        private class CustomMessage
        {
            public int type { get; set; }
            public string target { get; set; }
            public List<RedisMessage> arguments { get; set; }
        }
        private class RedisMessage
        {
            public string senderId { get; set; }
            public string message { get; set; }
            public DateTime sentAt { get; set; }
        }