Giter VIP home page Giter VIP logo

csredis's Introduction

csredis Build status

CSRedis is a .NET client for Redis and Redis Sentinel (2.8.12). Includes both synchronous and asynchronous implementations.

The easiest way to install CSRedis is from NuGet via the Package Manager Console:

PM> Install-Package csredis

Basic usage

Whenever possible, server responses are mapped to the appropriate CLR type.

using (var redis = new RedisClient("yourhost"))
{
    string ping = redis.Ping();
    string echo = redis.Echo("hello world");
    DateTime time = redis.Time();
}

Asynchronous commands are also available.

using (var redis = new RedisClient("localhost"))
{
    // fire-and-forget: results are not captured
    for (int i = 0; i < 5000; i++)
    {
        redis.IncrAsync("test1");
    }

    // callback via ContinueWith: Ping is executed asyncronously, and when a result is ready, the response is printed to screen.
    redis.TimeAsync().ContinueWith(t => Console.WriteLine(t.Result));

    // blocking call
    string result = redis.GetAsync("test1").Result;
}

Use the IRedisClient or IRedisClientAsync interfaces to use synconous or asyncronous methods exclusively.

using (IRedisClient csredis = new RedisClient(Host))
{
    // only syncronous methods exposed
}

using (IRedisClientAsync csredis = new RedisClient(Host))
{
    // only asyncronous methods exposed
}

Pipelining

CSRedis supports pipelining commands to lessen the effects of network overhead on sequential server calls. To enable pipelining, wrap a group of commands between StartPipe() and EndPipe(). Note that redis-server currently has a 1GB limit on client buffers but CSRedis does not enforce this. Similar performance gains may be obtained by using the deferred Task/Asyncronous methods.

using (var redis = new RedisClient("localhost"))
{
    redis.StartPipe();
    var empty1 = redis.Echo("hello"); // returns immediately with default(string)
    var empty2 = redis.Time(); // returns immediately with default(DateTime)
    object[] result = redis.EndPipe(); // all commands sent to the server at once
    var item1 = (string)result[0]; // cast result objects to appropriate types
    var item2 = (DateTime)result[1];

    // automatic MULTI/EXEC pipeline: start a pipe that is also a MULTI/EXEC transaction
    redis.StartPipeTransaction();
    redis.Set("key", "value");
    redis.Set("key2", "value2");
    object[] result2 = redis.EndPipe(); // transaction is EXEC'd automatically if DISCARD was not called first
    
    // DISCARD pipelined transaction
    redis.StartPipeTransaction();
    redis.Set("key", 123);
    redis.Set("key2", "abc");
    redis.Discard();
}

Why csredis?

There are a handful of .NET redis clients in active development, but none quite suited my needs: clean interface of the native Redis API; Sentinel support; easy-to-use pipelining/async. If there are gaps between CSRedis and another implementation please open an Issue or Pull Request.

Authentication

Password authentication is handled according to the native API (i.e. not in the connection constructor):

redis.Auth("mystrongpasword");

Reconnecting

CSRedis supports a simple reconnect option to handle dropped connections to the same Redis host. See RedisSentinelManager for a fuller implementation between multiple masters.

using (var redis = new RedisClient("localhost"))
{
    redis.Connected += (s, e) => redis.Auth(Password); // set AUTH, CLIENT NAME, etc
    redis.ReconnectAttempts = 3;
    redis.ReconnectWait = 200;
    // connection will retry 3 times with 200ms in between before throwing an Exception
}

Flexible hash mapping

Pass any POCO or anonymous object to the generic hash methods:

redis.HMSet("myhash", new
{
  Field1 = "string",
  Field2 = true,
  Field3 = DateTime.Now,
});

MyPOCO hash = redis.HGetAll<MyPOCO>("my-hash-key");

Or use a string Dictionary:

redis.HMSet("mydict", new Dictionary<string, string>
{
  { "F1", "string" },
  { "F2", "true" },
  { "F3", DateTime.Now.ToString() },
});

Dictionary<string, string> mydict = redis.HGetAll("my-hash-key");

Or use the native API:

redis.HMSet("myhash", new[] { "F1", "string", "F2", "true", "F3", DateTime.Now.ToString() });

Transactions

Synchronous transactions are handled using the API calls MULTI/EXEC/DISCARD. Attach an event handler to RedisClient.TransactionQueued event to observe server queue replies (typically 'OK'). When inside of a transaction, command return values will be default(T).

redis.TransactionQueued += (s, e) =>
{
    Console.WriteLine("Transaction queued: {0}({1}) = {2}", e.Command, String.Join(", ", e.Arguments), e.Status);
};
redis.Multi();
var empty1 = redis.Set("test1", "hello"); // returns default(String)
var empty2 = redis.Set("test2", "world"); // returns default(String)
var empty3 = redis.Time(); // returns default(DateTime)
object[] result = redis.Exec();
var item1 = (string)result[0];
var item2 = (string)result[1];
var item3 = (DateTime)result[2];

Subscription model

The subscription model is event based. Attach a handler to one or both of SubscriptionChanged/SubscriptionReceived to receive callbacks on subscription events. Opening the first subscription channel blocks the main thread, so unsubscription (and new subscriptions) must be handled by a background thread/task.

SubscriptionChanged: Occurs when a subscription channel is opened or closed
RedisSubscriptionReceived: Occurs when a subscription message has been received

Example:

redis.SubscriptionChanged += (s, e) =>
{
  Console.WriteLine("There are now {0} open channels", e.Response.Count);
};
redis.SubscriptionReceived += (s, e) =>
{
  Console.WriteLine("Message received: {0}", e.Message.Body);
};
redis.PSubscribe("*");

Future-proof

CSRedis exposes a basic Call() method that sends arbitrary commands to the Redis server. Use this command to easily implement future Redis commands before they are included in CSRedis. This can also be used to work with "bare-metal" server responses or if a command has been renamed in redis.conf.

object resp = redis.Call("ANYTHING", "arg1", "arg2", "arg3");

Note that the response object will need to be cast according to the Redis unified protocol: status (System.String), integer (System.Int64), bulk (System.String), multi-bulk (System.Object[]).

Streaming responses

For large result sizes, it may be preferred to stream the raw bytes from the server rather than allocating large chunks of memory in place. This can be achieved with RedisClient.StreamTo(). Note that this only applies to BULK responses (e.g. GET, HGET, LINDEX, etc). Attempting to stream any other response will result in an InvalidOperationException. Here is an example that stores the response in a MemoryStream 64 bytes at a time. A more useful example might use a FileStream and a larger buffer size.

redis.Set("test", new string('x', 1048576)); // 1MB string
using (var ms = new MemoryStream())
{
    redis.StreamTo(ms, 64, r => r.Get("test")); // read in small 64 byte blocks
    byte[] bytes = ms.ToArray(); // optional: get the bytes if needed
}

Tracing

Use .NET tracing to expose low level TCP messages

Sentinel

RedisSentinelManager is a managed connection that will automatically obtain a connection to a Redis master node based on information from one or more Redis Sentinel nodes. Async methods coming soon

using (var sentinel = new RedisSentinelManager("host1:123", "host2:456"))
{
    sentinel.Add(Host); // add host using default port 
    sentinel.Add(Host, 36379); // add host using specific port
    sentinel.Connected += (s, e) => sentinel.Call(x => x.Auth(Password)); // this will be called each time a master connects
    sentinel.Connect("mymaster"); // open connection
    var test2 = sentinel.Call(x => x.Time()); // use the Call() lambda to access the current master connection
}

csredis's People

Contributors

anshul-s avatar bryant1410 avatar ctstone avatar joseph-melberg avatar rabchev avatar rfranke avatar vgarcia330 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

csredis's Issues

Exception when IncrAsync

I write test codes following the example code in readme.md:
using (var redis = new RedisClient("someIP"))
{
// fire-and-forget: results are not captured
for (int i = 0; i < 5000; i++)
{
redis.IncrAsync("test1");
}
...
}
when i=0 it's fine,
when i=1, I got exception:
在已经完成任务后,尝试将任务转换为最终状态。(try transfer task to complete status when task is already completed.)
the stack is:

csredis.dll!CSRedis.Internal.IO.AsyncConnector.ConnectAsync() Line 51 C#
csredis.dll!CSRedis.Internal.IO.AsyncConnector.CallAsync(CSRedis.RedisCommand command) Line 73 C#
csredis.dll!CSRedis.Internal.RedisConnector.CallAsync(CSRedis.RedisCommand command) Line 97 C#
csredis.dll!CSRedis.RedisClient.WriteAsync(CSRedis.RedisCommand command) Line 34 C#
csredis.dll!CSRedis.RedisClient.IncrAsync(string key) Line 1530 C#
TestApp.exe!TestApp.Program.Main(string[] args) Line 21 C#
the code throw excetion is:
public Task ConnectAsync()
{
if (_redisSocket.Connected)
=> _connectionTaskSource.SetResult(true);

do I missunstand something about the async task?

Valid pull request rejected. Is the project still active?

Hi Chris:

I encountered an issue with the RedisSentinelManager, in which the host being saved included the port number. I also saw there is already a pull request for this fix, along with 2 other pull request. All the three pull request are marked as failed because of the same issue "Cryptographic failure while signing assembly".
I further realized the version labeled in the github project doesn't correspond with the latest version in the nuget.org site: the last label I see in the cloned repo is v 3.2.1.
Is the project still maintained, or am I missing something?
Thanks a lot.

async methods not working?

I'm trying to use HIncrByFloatAsync method;

var test =_client.HIncrByFloatAsync(currentKey, share.Miner.Username, share.Difficulty).Result;

And this doesn't thrown an exception (it should be doing so as I'm trying to set a non valid value)

But non-async seems to throw the exception i expect correctly

var test =_client.HIncrByFloat(currentKey, share.Miner.Username, share.Difficulty);

The error I expect;

ERR value is not a valid float

CSREDIS errors with CoiniumServ mining pool server.

Dears,

I have a two different problems problem as following with csredis.
Currently, I am using a CoiniumServ for my personal Cryptocurrency mining pool but I cannot use an information from redis server for hash rates etc. also on Windows, it generates BufferStream errors.

So I needed your support update a csredis package please

On Windows.
04/16/2017 21:03:43 +09:00 [Error] [HybridStorage] [Bitcoin] An exception occured while comitting share: Unexpected response type: MultiBulk (expecting Int)

23:35:27 [Error] [HybridStorage] [Bitcoin] An exception occured while comitting share: Cannot write to a BufferedStream while the read buffer is not empty if the underlying stream is not seekable. Ensure that the stream underlying this BufferedStream can seek or avoid interleaving read and write operations on this BufferedStream.

For Linux,
It does not recognize an installed redis server at all. it shows me the following error whenever I running a CoiniumServ on Ubuntu Linux server.

14:17:24 [Error] [RedisProvider] [Bitcoin] Redis storage initialization failed: 127.0.0.1:6379 - The requested feature is not implemented.

Regards,
John Ahn

Troubles, when key contains special escape

I have a method, which add data to HSET
The key of рash is the path as Path.Combine

var baseAddress =Path.Combine(address,obj.GetType().FullName);
var pattern = baseAddress + "*";
var keys = await _client.KeysAsync(pattern);
var properties = obj.GetProperties();
await _client.HSetAsync(Path.Combine(baseAddress,keys.Length.ToString()),
key,value);

In redis, the key is written including special escape as `"a\\c" (for example)

When i try to get a list of keys using KeysAsync(pattern) i get an empty list
If in the search pattern i replace all special escape (example: "a\\c" to "a\\\\c" ) i get true result

Help solve the problem?

Why in KeysAsync and HSetAsync keys are interpreted differently?

Connect Timeout TODO

Hi,

Is there any plan to update RedisSentinelClient connect timeout (TODO issue)?

    /// <summary>
    /// Connect to the remote host
    /// </summary>
    /// <param name="timeout">Connection timeout in milliseconds</param>
    /// <returns>True if connected</returns>
    public bool Connect(int timeout)
    {
        return _connector.Connect(); // TODO: timeout
    }

Regards

Exceptions when running load test

Hi there,

I was wondering if I could get a little help with some exceptions that crop up when I run a load test against my site.

During the test I see a lot of RedisClient is not connected.

System.InvalidOperationException: RedisClient is not connected
   at ctstone.Redis.RedisClient.Write[T](RedisCommand`1 command)

An example of the code that causes this

    public Member Get(int userId)
    {
        using (var client = redisClientFactory.Create())
        {
            var result = client.Get(key(userId));
            return String.IsNullOrEmpty(result)
                ? null
                : JsonConvert.DeserializeObject<Member>(result);
        }
    }

    public RedisClient Create()
    {
        return new RedisClient(host, port, timeoutInMilliseconds);
    }

From what I can tell this is fairly standard usage no?

Thanks
Neil

Code issue leading to data corruption

Thank you for the great redis client library for C#!

There is a code issue where data pulled out of redis will be incomplete and will be missing some bytes from the beginning of the stream. This is because of the RedisReader.cs line 72 and 91, the second argument to stream.Read should be bytes_read and not 0.

redispipeline flush() not supported exception

Using pipelines and similar to exception in; #17

System.NotSupportedException was unhandled by user code
  HResult=-2146233067
  Message=Cannot write to a BufferedStream while the read buffer is not empty if the underlying stream is not seekable. Ensure that the stream underlying this BufferedStream can seek or avoid interleaving read and write operations on this BufferedStream.
  Source=mscorlib
  StackTrace:
       at System.IO.BufferedStream.ClearReadBufferBeforeWrite()
       at System.IO.BufferedStream.Write(Byte[] array, Int32 offset, Int32 count)
       at System.IO.Stream.InternalCopyTo(Stream destination, Int32 bufferSize)
       at CSRedis.Internal.RedisPipeline.Flush() in f:\Source\CoiniumServ\deps\csredis\CSRedis\Internal\RedisPipeline.cs:line 38
       at CSRedis.Internal.RedisConnection.EndPipe() in f:\Source\CoiniumServ\deps\csredis\CSRedis\Internal\RedisConnection.cs:line 155
       at CSRedis.RedisClient.EndPipe() in f:\Source\CoiniumServ\deps\csredis\CSRedis\RedisClient.cs:line 175
       at CoiniumServ.Persistance.Redis.RedisCS.AddShare(IShare share) in f:\Source\CoiniumServ\src\CoiniumServ\Persistance\Redis\RedisCS.cs:line 95
       at CoiniumServ.Shares.ShareManager.HandleValidShare(IShare share) in f:\Source\CoiniumServ\src\CoiniumServ\Shares\ShareManager.cs:line 105
       at CoiniumServ.Shares.ShareManager.ProcessShare(IStratumMiner miner, String jobId, String extraNonce2, String nTimeString, String nonceString) in f:\Source\CoiniumServ\src\CoiniumServ\Shares\ShareManager.cs:line 86
       at CoiniumServ.Server.Mining.Stratum.Service.StratumService.SubmitWork(String user, String jobId, String extraNonce2, String nTime, String nonce) in f:\Source\CoiniumServ\src\CoiniumServ\Server\Mining\Stratum\Service\StratumService.cs:line 95
  InnerException: 

caused by;

                if (!IsEnabled || !IsConnected)
                    return;

                var coin = _poolConfig.Coin.Name.ToLower(); // the coin we are working on.

                _client.StartPipe(); // batch the commands.

                // add the share to round 
                var currentKey = string.Format("{0}:shares:round:current", coin);
                _client.HIncrByFloat(currentKey, share.Miner.Username, share.Difficulty);

                // increment shares stats.
                var statsKey = string.Format("{0}:stats", coin);
                _client.HIncrBy(statsKey, share.IsValid ? "validShares" : "invalidShares", 1);

                // add to hashrate
                if (share.IsValid)
                {
                    var hashrateKey = string.Format("{0}:hashrate", coin);
                    var entry = string.Format("{0}:{1}", share.Difficulty, share.Miner.Username);
                    _client.ZAdd(hashrateKey, Tuple.Create(TimeHelpers.NowInUnixTime(), entry));
                }

                _client.EndPipe(); // execute the batch commands.

Missing Files

Hi,

Looks like you're missing a couple of files from source. I noticed when I was trying to build this evening.

Debug/ActivityTracer.cs
Tests/App.config

Thanks
Neil

Got exception after setting value

redis.HMSet(key, objects);

Exception: System.Security.VerificationException: Operation could destabilize the runtime.
P.S. objects = List of my custom class.

Out of memory exception comeing from the dispose function

this happens once in a while when running the app locally, also it happens when running unit tests in a group when one of the tests is using csRedis.

at CSRedis.Internal.IO.SocketAsyncPool..ctor(Int32 concurrency, Int32 bufferSize)
at CSRedis.Internal.RedisConnector.SocketAsyncPoolFactory()
at System.Lazy1.CreateValue() at System.Lazy1.LazyInitValue()
at System.Lazy`1.get_Value()
at CSRedis.Internal.RedisConnector.Dispose()
at CSRedis.RedisClient.Dispose()

will be happy to answer question and add data if you tell me what you want to know.

thanks.

Connection timeout

I'm trying to use your library, but I'm getting a strange problem. After short period of time (couple minutes) executing RedisClient.publish throws RedisProtocolException Unexpected response type: -1 (expecting Int)

Publishing few messages works and then, when I let it sit for a few minutes, it seems to timeout the connection? Is there any reconnection logic in the driver? I didn't see any.

CsRedis:从始至终偶尔/经常性都报异常,异常原因,初步判断是流程问题, 测试String 字符串插入

CsRedis:从始至终都报异常,异常原因,初步判断是流程问题,

  • 已经被销毁的对象,被程序某处调用引发内部异常.
得出结论: 

Newlife.Redis 与 CsRedis:从始至终 均在初始阶段报异常.

Newlife.Redis : 
我看了是dynamic 一个属性问题.问题不大.
后面运行均稳定不报错的执行任务!

CsRedis:从始至终都报异常,异常原因,初步判断是流程问题,
已经被销毁的对象,被程序某处调用引发内部异常.

我均不知道这样是否影响正常无大碍使用,但是看到异常,就很强迫症.修下.
这个issue我会开个看是否是确实存在我所测的情况.然后修复下.  

avatar

avatar

Demo代码

  • CsRedis 代码
            var csredis = new CSRedis.CSRedisClient("127.0.0.1:6379,password=,defaultDatabase=3,prefix=app_");

            RedisHelper.Initialization(csredis);

            Parallel.For(0, 50000000, new ParallelOptions() { MaxDegreeOfParallelism = 100 }, (i, loopState) =>
            {
                try
                {
                    RedisHelper.Set(GuidExtenions.N, "1111999", 180);
                }
                catch (Exception)
                {
                   //这里很容易爆各种异常,这个异常原因没搞明白 我坚持写完5000万 key先看会产生什么.暂时把异常处理掉.
                }
            });
  • Newlife.Redis 代码
            var rds = new NewLife.Caching.FullRedis("127.0.0.1:6379", "", 1)
            { 
            };

            Parallel.For(0, 50000000, new ParallelOptions() { MaxDegreeOfParallelism = 100 }, (i, loopState) =>
            {
                try
                {
                    rds.Set(GuidExtenions.N, "1111999", 180);
                }
                catch (Exception)
                {

                    //这里很容易爆各种异常,这个异常原因没搞明白 我坚持写完5000万 key先看会产生什么.暂时把异常处理掉.
                } 
            });

When I execute in parallel

error:
如果基础流不可搜寻,则当读取缓冲区不为空时,将无法写入到 BufferedStream。确保此 BufferedStream 下的流可搜寻或避免对此 BufferedStream 执行隔行读取和写入操作。
在 System.IO.BufferedStream.ClearReadBufferBeforeWrite()
在 System.IO.BufferedStream.Write(Byte[] array, Int32 offset, Int32 count)
在 CSRedis.Internal.IO.RedisWriter.Write(RedisCommand command, Stream stream) 位置 D:\HProject\OpenSourceProject\csredis\CSRedis\Internal\IO\RedisWriter.cs:行号 27
在 CSRedis.Internal.RedisConnector.Call[T](RedisCommand1 command) 位置 D:\HProject\OpenSourceProject\csredis\CSRedis\Internal\RedisConnector.cs:行号 83 在 CSRedis.RedisClient.Write[T](RedisCommand1 command) 位置 D:\HProject\OpenSourceProject\csredis\CSRedis\RedisClient.Sync.cs:行号 42

Does this project still accept contribution?

I understand that this project has been inactive for a few years. .NET core is getting popular now. I'm not sure if you need contribution on .NET core version of csredis?

Let me know your idea. Thanks

ExpressionTree's in Serializer.cs

Hey guys

I'm sorry for my ignorance but could you please explain what the benefits of ExpressionTree based implementation in Serializer.cs ?

"Member 's-down-time' was not found." error

I have a strange issue with csredis' RedisSentinelManager(). I am adding sentinels as below

            var sentinel = new RedisSentinelManager();
            sentinel.Add("ttekhysred01", 20001);
            sentinel.Add("ttekhysred01", 20002);

            sentinel.Connected += (s, e) => sentinel.Call(x => x.Auth(password));
            sentinel.Connect("mymaster", 200);

When executing the code I get, "Member 's-down-time' was not found." error. Is there something with sentinel configuration or somehing else.

socket error

any idea what is the reason for this?

i am creating a new csRedis client for every request. is this a bad practice? i know clients like SE.redis reuse the connection. but the examples on this repo show the using statement so that is what i did.

System.Net.Sockets.SocketException (0x80004005): Only one usage of each socket address (protocol/network address/port) is normally permitted 191.234.53.96:6379
at System.Net.Sockets.Socket.Connect(IPAddress[] addresses, Int32 port)
at System.Net.Sockets.Socket.Connect(String host, Int32 port)
at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
at CSRedis.Internal.RedisConnector.Connect()
at CSRedis.Internal.RedisConnector.Call[T](RedisCommand1 command) at CSRedis.RedisClient.Write[T](RedisCommand1 command)
at Common.Cache.csRedis.AddStringToCache(String key, String value, Nullable`1 minutes)

select & mono - The requested feature is not implemented.

Using csredis with mono.

Using sync client - and select command

                // create the connection
                Client = new RedisClient(_config.Host, _config.Port)
                {
                    ReconnectAttempts = 3,
                    ReconnectWait = 200
                };

Client.Select(_config.DatabaseId);

Getting;


any ideas?

OverflowException in BLPop

An OverflowException occors after the BLPop command times out.
client.BLPop(TimeSpan.FromSeconds(10), "listname");
After 10 seconds this exception is thrown, if now item could be popped within 10 seconds.
System.OverflowException: Arithmetic operation resulted in an overflow.
at CSRedis.Internal.Commands.RedisArray.IndexOf1.Parse(RedisReader reader) RedisArray.cs:line 82 at CSRedis.Internal.RedisConnector.Call[T](RedisCommand1 command) RedisConnector.cs:line 84
at CSRedis.RedisClient.Write[T](RedisCommand`1 command) RedisClient.Sync.cs:line 42
at CSRedis.RedisClient.BLPop(Int32 timeout, String[] keys) RedisClient.Sync.cs:line 640

Missing License?

It looks like there isn't an OSS License applied to this project. It's best practice to display what license you want to protect this work under.

C# Consumer Class using RedisSubscriptionClient

Hi,
I'm asking help for a sample C# Consumer class based on csredis and RedisSubscriptionClient .
As a newcomer to C#, I recently discovered there are multiples ways of writing such a class, lambda expressions, callbacks, delegates etc.. Well I'm just looking for the simpliest solution that works. I read the samples but didnt find any complete consumer class here, nor in servicestack redis.
I tested my Producer Class with redis-cli and "monitor", it works fine, I can see the messages posted.
Thanks in advance.
Cheers

Here is the codefor my Consumer Class at the moment

using ctstone.Redis;
using NUnit.Framework;
public class Consumer : IDisposable
{
protected RedisSubscriptionClient sub;
protected string Channel;
public delegate void onSuscriptionReceived(object sender, EventArgs e);
public event onSuscriptionReceived received;
public Consumer(string symbol)
{
Channel = symbol;
sub = new RedisSubscriptionClient("localhost", 6379, "");
sub.SubscriptionReceived += (o, e) => { /* what do I put here ? /};
sub.Subscribe(Channel);
}
public void Dispose()
{
/
what do I put here ? / }
}
public void ProcessMessageDelegate(object sender, EventArgs e)
{
/
what do I put here ? */
}

and ..

        producer = new Producer("aChannel");
        consumer = new Consumer("aChannel");

        producer.SendMessage("test");

error On redisClient.Set(key,val,ttl)

only happens when:

the val is a string and that string is Json data created using Json.net.
the ttl is not null.

,"ExceptionMessage":"ERR Protocol error: expected '$', got ' '","ExceptionType":"CSRedis.RedisException","StackTrace":" at CSRedis.Internal.IO.RedisReader.ReadType()\r\n at CSRedis.Internal.Commands.RedisStatus.Nullable.Parse(RedisReader reader)\r\n at CSRedis.Internal.RedisConnector.Call[T](RedisCommand1 command)\r\n at CSRedis.RedisClient.Write[T](RedisCommand1 command)\r\n at CSRedis.RedisClient.Set(String key, Object value, Nullable`1 expiration

If i do the set and the expire in two steps there is no error
client.set(key,val);
client.Expire(key,ttl);

using this:
redisClient.Call("SET",key,val,ttl);
also gives the same error.

How to Subscribe

i use redis-client publish a message .

i subscribe in a Console app.

my code
image

Unexpected response type: 56 (expecting Bulk)

[Error] [HybridStorageLayer] [Lottocoin] An exception occured while comitting share: Unexpected response type: 56 (expecting Bulk) Fatal

Working with latest develop tree, the offending code;

try
            {
                if (!IsEnabled || !_redisProvider.IsConnected)
                    return;

                //_client.StartPipe(); // batch the commands.

                // add the share to round 
                var currentKey = string.Format("{0}:shares:round:current", _coin);
                _redisProvider.Client.HIncrByFloat(currentKey, share.Miner.Username, share.Difficulty);

                // increment shares stats.
                var statsKey = string.Format("{0}:stats", _coin);
                _redisProvider.Client.HIncrBy(statsKey, share.IsValid ? "validShares" : "invalidShares", 1);

                // add to hashrate
                if (share.IsValid)
                {
                    var hashrateKey = string.Format("{0}:hashrate", _coin);
                    var entry = string.Format("{0}:{1}", share.Difficulty, share.Miner.Username);
                    _redisProvider.Client.ZAdd(hashrateKey, Tuple.Create(TimeHelpers.NowInUnixTime(), entry));
                }

                //_client.EndPipe(); // execute the batch commands.
            }
            catch (Exception e)
            {
                _logger.Error("An exception occured while comitting share: {0:l}", e.Message);
            }

There is a problem in ReadByte()

public int ReadByte()
{
lock (_streamLock)
{
return Stream.ReadByte();
}
}
public virtual int ReadByte()
{
byte[] array = new byte[1];
if (Read(array, 0, 1) != 0)
{
return array[0];
}
return -1;
}
private string ReadLine()
{
if (!_io.Stream.CanRead)
{
return string.Empty;
}
StringBuilder stringBuilder = new StringBuilder();
bool flag = false;
while (true)
{
char c = (char)_io.ReadByte();
if (c == '\r')
{
flag = true;
continue;
}
if (c == '\n' && flag)
{
break;
}
stringBuilder.Append(c);
flag = false;
}
return stringBuilder.ToString();
}

This function does'nt judgment on returning -1.
It will reproduce the problem when i restart the reids,or in case of network anomaly with redis
I found these datas when i debugged with lldb

image

And then i suggest the following amendment
private string ReadLine()
{
if (!_io.Stream.CanRead)
{
return string.Empty;
}
StringBuilder stringBuilder = new StringBuilder();
bool flag = false;
int c = -1;
while ((c = _io.ReadByte()) != -1)
{
if ((char)c == '\r')
{
flag = true;
continue;
}
if (((char)c == '\n') || ((char)c == '\n' && flag))
{
break;
}
stringBuilder.Append((char)c);
flag = false;
}
return stringBuilder.ToString();
}

HashMapper.ToObject for Sentinel Nodes

When trying to get a master/slave, the library is issuing the "SENTINEL slaves mymaster" command. Which is returning...

  1. "name"
    2) "192.168.107.121:6401"
    3) "ip"
    4) "192.168.107.121"
    5) "port"
    6) "6401"
    7) "runid"
    8) "caadce2a27f1d705dc294f954e9fefd0afb20a40"
    9) "flags"
  2. "slave"
  3. "pending-commands"
  4. "0"
  5. "last-ping-sent"
  6. "0"
  7. "last-ok-ping-reply"
  8. "515"
  9. "last-ping-reply"
  10. "515"
  11. "down-after-milliseconds"
  12. "2000"
  13. "info-refresh"
  14. "4572"
  15. "role-reported"
  16. "slave"
  17. "role-reported-time"
  18. "4930667"
  19. "master-link-down-time"
  20. "0"
  21. "master-link-status"
  22. "ok"
  23. "master-host"

and many many more, currently it's failing to map those back to the objects using the code in ToObject.

            if (fieldValues.Length == 0)
                return default(T);
            var dict = new Dictionary<string, string>();
            for (int i = 0; i < fieldValues.Length; i += 2)
            {
                string key = fieldValues[i].ToString().Replace("-", String.Empty);
                if (key == "name")
                    key = "Name";
                string value = fieldValues[i + 1].ToString();
                dict[key] = value;
            }
            return Serializer<T>.Deserialize(dict);

Above this there are a few lines that are commented out

            T obj = Activator.CreateInstance<T>();

            TypeConverter conv;
            PropertyInfo prop;
            string field, value;
            for (int i = 0; i < fieldValues.Length; i += 2)
            {
                field = fieldValues[i].ToString().Replace("-", String.Empty);
                value = fieldValues[i + 1].ToString();
                prop = typeof(T).GetProperty(field, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
                if (prop == null || !prop.CanWrite)
                    continue;
                conv = TypeDescriptor.GetConverter(prop.PropertyType);
                if (!conv.CanConvertFrom(typeof(String)))
                    continue;
                if (prop.PropertyType == typeof(Boolean) && value == "1")
                    value = "true";
                prop.SetValue(obj, conv.ConvertFrom(value), null);
            }
            return obj;

All of which work a treat. I've swapped out the code again and it works again now. This probably isn't your fix, just bringing it to your attention.

jmeter 压力测试时的错误 对象池已释放,无法访问

System.ObjectDisposedException: Cannot access a disposed object.
Object name: '【192.168.3.13:6379/0】对象池已释放,无法访问。'.
at SafeObjectPool.ObjectPool1.getFree(Boolean checkAvailable) at SafeObjectPool.ObjectPool1.GetAsync()
at CSRedis.CSRedisClient.GetAndExecuteAsync[T](RedisClientPool pool, Func2 handerAsync, Int32 jump) at CSRedis.CSRedisClient.ExecuteScalarAsync[T](String key, Func3 handerAsync)

Support for .Net Core

Hi,

Is there a plan for looking at .Net Core support? Looked for but didn't see any discussion on it - sorry if this has already been addressed.

Thanks,
Sam

Slow Sentinel Performance

When trying to use csredis in a master->slave scenario using Sentinel, performance of getting slave/master is incredibly bad. See post on stack overflow...

http://stackoverflow.com/questions/22908507/redis-sentinel-c-sharp-client/22913368#22913368

According to the redgate profiler, RedisConnection.Dispose() is taking around 600ms each time (_asyncReader.Wait()) causing huge delays.

I have taken a copy of the code, removed all the Async code, and it storms through, getting a slave/master in under 10ms!

image

ERR unknown command 'ROLE'

var Host = "192.168.1.59";
using (var sentinel = new RedisSentinelManager("192.168.1.59:6389", "192.168.1.59:7389", "192.168.1.59:7390"))
{
sentinel.Add(Host); // add host using default port
sentinel.Add(Host, 26389); // add host using specific port
// sentinel.
// sentinel.Connected += (s, e) => sentinel.C; // this will be called each time a master connects
next line throw ERR unknown command 'ROLE'
sentinel.Connect("server-1M"); // open connection

            var test2 = sentinel.Call(x => x.Time()); // use the Call() lambda to access the current master connection
        }

Should support IPEndPoint as well as DnsEndPoint

Some of us are not fortunate enough to work in an organisation with such fanciful modern gizmos like DNS, despite our best efforts to drag them into the future. Thus we are relegated to using only IP addresses and this means CSRedis has real problems - particularly with Sentinels.

WriteAsync notsupported exception

Frequently happens within async methods;

RedisWriter.cs
        Task WriteAsync(byte[] data)
        {
            var tcs = new TaskCompletionSource<bool>();
            _streamBuffer.BeginWrite(data, 0, data.Length, ar =>
            {
                _streamBuffer.EndWrite(ar);
                tcs.SetResult(true);
            }, null);
            return tcs.Task;
        }
System.NotSupportedException was unhandled by user code
  HResult=-2146233067
  Message=Cannot write to a BufferedStream while the read buffer is not empty if the underlying stream is not seekable. Ensure that the stream underlying this BufferedStream can seek or avoid interleaving read and write operations on this BufferedStream.
  Source=mscorlib
  StackTrace:
       at System.IO.BufferedStream.ClearReadBufferBeforeWrite()
       at System.IO.BufferedStream.BeginWrite(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
       at CSRedis.Internal.IO.RedisWriter.WriteAsync(Byte[] data) in e:\Coding\CoiniumServ\deps\csredis\CSRedis\Internal\IO\RedisWriter.cs:line 166
       at CSRedis.Internal.IO.RedisWriter.WriteMultiBulkAsync(Int32 size) in e:\Coding\CoiniumServ\deps\csredis\CSRedis\Internal\IO\RedisWriter.cs:line 86
       at CSRedis.Internal.IO.RedisWriter.WriteAsync(String command, Object[] args) in e:\Coding\CoiniumServ\deps\csredis\CSRedis\Internal\IO\RedisWriter.cs:line 47
       at CSRedis.Internal.RedisConnection.<>c__DisplayClass6`1.<CallAsync>b__2() in e:\Coding\CoiniumServ\deps\csredis\CSRedis\Internal\RedisConnection.cs:line 105
       at CSRedis.Internal.RedisConnection.WriteNext() in e:\Coding\CoiniumServ\deps\csredis\CSRedis\Internal\RedisConnection.cs:line 198
       at CSRedis.Internal.RedisConnection.<CallAsync>b__5[T](Task`1 x) in e:\Coding\CoiniumServ\deps\csredis\CSRedis\Internal\RedisConnection.cs:line 109
       at System.Threading.Tasks.Task.Execute()
  InnerException: 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.