Redis隨筆(六)RESP的協議規範

1、官網文檔

https://redis.io/topics/protocol

http://www.redis.cn/topics/protocol.html
2、協議介紹

redis協議規範(Redis Protocol specification)。

redis協議在以下幾點之間做出了折衷:

(1)簡單的實現

(2)快速地被計算機解析

(3)簡單得可以能被人工解析

(4)網絡層,Redis在TCP端口6379上監聽到來的連接(本質就是socket),客戶端連接到來時,Redis服務器爲此創建一個TCP連接。在客戶端與服務器端之間傳輸的每個Redis命令或者數據都以\r\n結尾。
3、請求

Redis接收由不同參數組成的命令。一旦收到命令,將會立刻被處理,並回復給客戶端
4、新的統一請求協議

在這個統一協議裏,發送給Redis服務端的所有參數都是二進制安全的。以下是通用形式:

*後面數量表示存在幾個$
$後面數量表示字符串的長度

例子:
複製代碼

*3
$3
SET
$5
mykey
$7
myvalue

複製代碼

上面的命令看上去像是單引號字符串,所以可以在查詢中看到每個字節的準確值:

“*3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$7\r\nmyvalue\r\n”

在Redis的回覆中也使用這樣的格式。批量回復時,這種格式用於每個參數$6\r\nmydata\r\n。 實際的統一請求協議是Redis用於返回列表項,並調用 Multi-bulk回覆。 僅僅是N個以以*\r\n爲前綴的不同批量回復,是緊隨的參數(批量回復)數目。
5、回覆

Redis用不同的回覆類型回覆命令。它可能從服務器發送的第一個字節開始校驗回覆類型:

(1)用單行回覆,回覆的第一個字節將是“+”

(2)錯誤消息,回覆的第一個字節將是“-”

(3)整型數字,回覆的第一個字節將是“:”

(4)批量回復,回覆的第一個字節將是“$”

(5)多個批量回復,回覆的第一個字節將是“*”

例子:狀態回覆(或者單行回覆)

以“+”開始以“\r\n”結尾的單行字符串形式。例如:

“+OK\r\n”

客戶端庫將在“+”後面返回所有數據,正如上例中字符串“OK”一樣。

有關與其他的操作請查看官方文檔。
6、模擬Redis服務和客戶端通訊,實現RESP協議通信

枚舉類

public enum CommandRedis {
SET, GET, SETNX
}

實現類
複製代碼

package com.protocol;

import org.junit.Test;

import java.io.IOException;
import java.net.Proxy;
import java.net.Socket;

/**

  • Created by wxh on 2018/1/29.
    */
    public class RedisClientByResp {

    private Socket socket;

    public RedisClientByResp() {
    try {
    socket = new Socket(“192.168.56.180”, 6379);
    } catch (IOException e) {
    e.printStackTrace();
    System.out.println(“連接失敗” + e.getMessage());
    }
    }

    /**

    • 設置值

    • @param key

    • @param value

    • @return

    • @throws IOException
      */
      public String set(String key, String value) throws IOException {
      StringBuilder sb = new StringBuilder();
      sb.append("*3").append("\r\n");
      sb.append("KaTeX parse error: Can't use function '\r' in math mode at position 53: …gth()).append("\̲r̲\n"); sb.appen…").append(key.getBytes().length).append("\r\n");
      sb.append(key).append("\r\n");
      sb.append("$").append(value.getBytes().length).append("\r\n");
      sb.append(value).append("\r\n");
      System.out.println(sb.toString());

      socket.getOutputStream().write(sb.toString().getBytes());
      byte[] b = new byte[2048];
      socket.getInputStream().read(b);
      return new String(b);
      }

    /**

    • 獲取值

    • @param key

    • @return

    • @throws Exception
      */
      public String get(String key) throws Exception {
      StringBuffer stringBuffer = new StringBuffer();
      stringBuffer.append("*2").append("\r\n");
      stringBuffer.append("KaTeX parse error: Can't use function '\r' in math mode at position 53: …gth()).append("\̲r̲\n"); stringBu…").append(key.getBytes().length).append("\r\n");
      stringBuffer.append(key).append("\r\n");

      socket.getOutputStream().write(stringBuffer.toString().getBytes());
      byte[] b = new byte[2048];
      socket.getInputStream().read(b);
      return new String(b);
      }

    /**

    • 設置值:不會覆蓋存在的值

    • @param key

    • @param value

    • @return

    • @throws Exception
      */
      public String setnx(String key, String value) throws Exception {
      StringBuffer stringBuffer = new StringBuffer();
      stringBuffer.append("*3").append("\r\n");
      stringBuffer.append("KaTeX parse error: Can't use function '\r' in math mode at position 55: …gth()).append("\̲r̲\n"); stringBu…").append(key.getBytes().length).append("\r\n");
      stringBuffer.append(key).append("\r\n");
      stringBuffer.append("$").append(value.getBytes().length).append("\r\n");
      stringBuffer.append(value).append("\r\n");

      socket.getOutputStream().write(stringBuffer.toString().getBytes());
      byte[] b = new byte[2048];
      socket.getInputStream().read(b);
      return new String(b);
      }

    public static void main(String[] args) throws Exception {
    System.out.println(new RedisClientByResp().set(“mykey” ,“myvalue”));
    System.out.println(new RedisClientByResp().get(“mykey”));
    }
    }

複製代碼

轉自文件 https://www.cnblogs.com/c-xiaohai/p/8376891.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章