One of the things I need to do is to get/set/subscribe to deal with byte arrays. So far, I have:
redisNativeClient = redisFactory.GetDisposableClient<ServiceStack.Redis.RedisNativeClient>();
byte baResponse = redisNativeClient.Client.Get(sChannel);
public void PublishAndSetValue(string sChannel, byte baValues)
And this is the part where I’m stuck:
redisFactory = new ServiceStack.Redis.PooledRedisClientManager(sHost);
redisPubSubServer = new ServiceStack.Redis.RedisPubSubServer(redisFactory, saSubscribeToChannels);
redisPubSubServer.OnMessage += RedisMessageReceivedHandler;
OnMessage is Action<string, string>.
Is there Action<string, byte> OnMessageBytes or anything like that? I’d hate to convert the string back to a byte array for performance reasons.
March 29, 2019, 4:05pm
No there’s only a
string so you’d need to either send the payload as base64 or do something like send a key that references a byte value that subscribers download themselves as would be the optimal strategy for sending large payloads.
They’re not large, rather there’s many, many small ones. The back and forth from byte array to UTF8 creates problems in that it’s not reversible, for example - the following breaks on round trip
I would be inclined to call this a bug.
byte baEncoded = GetBytesForData(); //40 Bytes
string sToString = Encoding.UTF8.GetString(baEncoded);
byte baDecoded = Encoding.UTF8.GetBytes(sToString); //68 Bytes!!!!
protected unsafe byte GetBytesForData()
int iByteSize = sizeof(long);
if (iByteSize != sizeof(double)) throw new DataMisalignedException();
byte array = new byte[5 * iByteSize];
fixed (byte* byteptr = array)
double* dblptr = (double*)byteptr;
long* longptr = (long*)byteptr;
longptr = 1;
dblptr = 2.3;
dblptr = 4.5;
dblptr = 6.7;
longptr = -8;
March 29, 2019, 6:32pm
You should be sending binary over text as a
Base64 string, i.e. Use
I thought strings in Redis were binary-safe, no?
April 1, 2019, 1:44pm
This has nothing to do with Redis.
You can’t use UTF-8 text encoding to encode binary data, it’s for encoding
text which C# strings stores as UTF-16 surrogate pairs into UTF-8 bytes.
By far the most popular way to encode binary data to text in .NET is to use Base64, which is what you should be using instead.
Unfortunately, I’m not the sole user of this Redis database, and my role is rather limited. The other people using it are not even using .NET, they’re using C on Linux. Their idea is to pull the bytes, and do something like this:
void UnpackBytes(unsigned char* data)
SOMEData someData = (SOMEData)data;
Assuming the other users won’t go along with the Base64 paradigm, that’s why I was wondering if there should be Action<string, byte> OnMessageBytes or if I’ll need to handle RedisNativeClient to get the bytes.
April 1, 2019, 8:18pm
You wont be able to transfer arbitrary binary data over strings without encoding it, i.e. you can’t unpack bits from a string.
But I’ve added
OnMessageBytes to both
this commit which will let you read the message body as bytes.
This change is available from v5.5.1 that’s now
available on MyGet.
Yes, excellent point. I hate that Redis calls the data type a string when it can be used to transfer non-string bytes. But anyway, this change is working beautifully well, much appreciated!