Introduced
The Redis client is being modified in the recent project use. Just read the following document, summarize and share a bit.
Directory
One: Protocol specification
II: Basic Communication
Three: Status command
Four: set, get command
V: Pipelines, services
VI: summary
One: Protocol specification
Redis allows clients to connect in TCP, with the default port of 6379. The transfer data ends with \ r \ n.
Request format
*<number of Arguments>\r\n$<number of bytes of argument 1>\r\n <argument data>\r\n
Example: *1\r\n$4\r\ninfo\r\n
Response format
1: Simple string, non-binary secure string, typically a state reply. + Beginning, example: +ok\r\n
2: Error message. - Beginning, example:-err unknown command ' mush ' \ r \ n
3: Integer number. : Beginning, example:: 1\r\n
4: Bulk reply value, Max 512M. $ Start + data length. Example: $4\r\mush\r\n
5: Multiple replies. * Beginning, example: *2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n
II: Basic Communication
To define a configuration class:
public class Configuration {public string Host {get; set;} public int Port {get; set;} <summary>// whether the Socket is using the Nagle algorithm. // </summary> public bool Nodelaysocket {get; set;} Public Configuration () { Host = "localhost"; Port = 6379; Nodelaysocket = false; } }
To implement a socket connection:
Public classredisbaseclient {//configuration file Privateconfiguration configuration; //Communication Socket Privatesocket socket; //receive byte array Private byte[] Receivebuffer =New byte[100000]; Publicredisbaseclient (configuration config) {configuration=config; } Publicredisbaseclient (): This(NewConfiguration ()) { } Public voidConnect () {if(Socket! =NULL&&socket. Connected)return; Socket=NewSocket (AddressFamily.InterNetwork, SocketType.Stream, protocoltype.tcp) {Nodelay=configuration. Nodelaysocket}; Socket. Connect (configuration. Host, configuration. Port); if(socket.) Connected)return; Close (); } /// <summary> ///Close Client/// </summary> Public voidClose () {socket. Disconnect (false); Socket. Close (); } }
Call:
New redisbaseclient (); Redis. Connect ();
Server-Side Successful response:
Three: Status command
To define a REDIS command enumeration:
Public enum Rediscommand { // Get the value of a key // Redis information. // Add a value // set Expiration Time // Mark a transaction block start // execute all MULTI after the command }
Send command build:
Public stringSendCommand (Rediscommand command,params string[] args) { //Request Header format, *<number of arguments>\r\n Const stringHeadstr ="*{0}\r\n"; //parameter information $<number of bytes of argument n>\r\n<argument data>\r\n Const stringBulkstr ="${0}\r\n{1}\r\n"; varSB =NewStringBuilder (); Sb. AppendFormat (Headstr, args. Length+1); varcmd =command. ToString (); Sb. AppendFormat (Bulkstr, cmd. Length, CMD); foreach(varArginchargs) {sb. AppendFormat (Bulkstr, Arg. Length, ARG); } byte[] C =Encoding.UTF8.GetBytes (sb.) ToString ()); Try{Connect (); Socket. Send (c); Socket. Receive (Receivebuffer); Close (); returnReadData (); } Catch(SocketException e) {Close (); } return NULL; } Private stringReadData () {vardata =Encoding.UTF8.GetString (Receivebuffer); Charc = data[0]; //error message check. if(c = ='-')//exception handling. Throw NewException (data); //status reply. if(c = ='+') returndata; returndata; }
Call:
private void Button1_Click (object sender, EventArgs e) { redisbaseclient Redis = new Redisbaseclient (); var result = Redis. SendCommand (rediscommand.info); richTextBox1.Text = result; }
Response output. 937 is the data length.
Four: set, get command
Call:
Private voidButton2_Click (Objectsender, EventArgs e) {redisbaseclient Redis=Newredisbaseclient (); varresult = Redis. SendCommand (Rediscommand.set,"msg","TestValue"); richTextBox1.Text=result. ToString (); } Private voidButton3_Click (Objectsender, EventArgs e) {redisbaseclient Redis=Newredisbaseclient (); varresult = Redis. SendCommand (Rediscommand.get,"msg"); richTextBox1.Text=result. ToString (); }
Output
V: Pipelines, services
Both are walking multi,exec commands, atomic operations. The pipeline is the Send command (no wait for the last command reply), enters the command queue, then executes multiple commands at once and returns the client result.
We usually use the Servicestack.redis client directly set, in fact, is set, expire 2 commands . The simple implementation is as follows:
Public voidCreatepipeline () {SendCommand (Rediscommand.multi,New string[] {},true); } Public stringEnqueuecommand (Rediscommand command,params string[] args) { returnSendCommand (command, args,true); } Public stringFlushpipeline () {varresult = SendCommand (rediscommand.exec,New string[] {},true); Close (); returnresult; } Public stringSendCommand (Rediscommand command,string[] args,BOOLIspipeline=false) { //Request Header format, *<number of arguments>\r\n Const stringHeadstr ="*{0}\r\n"; //parameter information $<number of bytes of argument n>\r\n<argument data>\r\n Const stringBulkstr ="${0}\r\n{1}\r\n"; varSB =NewStringBuilder (); Sb. AppendFormat (Headstr, args. Length+1); varcmd =command. ToString (); Sb. AppendFormat (Bulkstr, cmd. Length, CMD); foreach(varArginchargs) {sb. AppendFormat (Bulkstr, Arg. Length, ARG); } byte[] C =Encoding.UTF8.GetBytes (sb.) ToString ()); Try{Connect (); Socket. Send (c); Socket. Receive (Receivebuffer); if(!ispipeline) {Close (); } returnReadData (); } Catch(SocketException e) {Close (); } return NULL; } Public stringSetbypipeline (stringKeystringValueintsecond) { This. Createpipeline (); This. Enqueuecommand (Rediscommand.set, key, value); This. Enqueuecommand (Rediscommand.expire, Key, second. ToString ()); return This. Flushpipeline (); }
Call:
Private void button4_click (object sender, EventArgs e) { new Redisbaseclient (); = Redis. Setbypipeline ("cnblogs""mushroom"1000 ); }
Output:
2 replies.
VI: summary
This article is just a simple implementation. Interested classmates, can continue to go on. PS: A little repetition of the feeling of making wheels.
Client implementation of this block, socket connection pool management is more complex.
Reference Resources
1:http://redis.io/topics/protocol
2:https://github.com/servicestack/servicestack.redis
If there is any mistake, please point out the correct, help you, recommend the next n (* ≧▽≦ *) n.
Mr. Mushroom
Source: http://www.cnblogs.com/mushroom/p/4217541.html
C # Implementing Redis Client (i)