skip to Main Content

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

"x92x90x81xa4jsonxc4x83{"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();
    }
}

2

Answers


  1. Please try to use below code.

        public IActionResult testmsg()
        {
            string input = "x92x90x81xa4jsonxc4x83{"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; }
        }
    
    Login or Signup to reply.
  2. The message is a MessagePack-encoded binary message that contains a JSON payload.
    The "x92" and "x90" bytes at the beginning of the message are part of the MessagePack header and indicate that the message is an array with two elements. The "x81" byte indicates that the first element of the array is a map with one key-value pair. The key is the string "json" and the value is a MessagePack-encoded string that contains the JSON payload. The "xc4x83" bytes indicate that the string is 3 bytes long.
    for using it , you can install NuGet package MessagePack and then use MessagePackSerializer class like this :

    var dictionary = MessagePackSerializer.Deserialize<Dictionary<object, object>>(yourInput);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search