シミュレーションjedis、RESPプロトコルを使用してRedis 5に接続

24545 ワード

resp(REdis Serialization Protocol)は、respがシーケンス化プロトコルであることがわかります.respは実現が簡単で、解析が速く、読みやすい特性を持っています.jedisソースコードを見たり、パッケージツールを使ったりして、respプロトコルデータを見ることができます.明らかにrespはバイナリで安全であり、各データユニットの前に対応する長さ識別がある.
基本的には以下の行を読めばいいです.
*2
$4
auth
$5
redis5

*+数値:配列長$+数値を表す:文字列長(バイト長)authでset,getなどのredisの操作コマンドがリターン改行で終わることを示す.
クライアントはtcp接続とredisサービス側通信を使用し、通常のsocketプログラミングであり、socketがredisサーバに接続されている限り、respプロトコルデータをサービス側に送信することができる.
public class TestResp {

    Socket socket;

    public TestResp(Socket socket) {
        this.socket = socket;
    }

    public TestResp(String host,int port) {
        Socket socket = null;
        try {
            socket = new Socket(host, port);
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.socket = socket;
    }

    static final String lineSeparator = System.getProperty("line.separator");
	
	/**   auth   */
    private void auth(String password) throws IOException {
        StringBuffer authSb = new StringBuffer();
        authSb.append("*2").append(lineSeparator);
        authSb.append("$").append("auth".getBytes().length).append(lineSeparator);
        authSb.append("auth").append(lineSeparator);
        authSb.append("$").append(password.getBytes().length).append(lineSeparator);
        authSb.append(password).append(lineSeparator);

        OutputStream out = socket.getOutputStream();
        out.write(authSb.toString().getBytes());
        out.flush();
        byte[] authResp = new byte[1024];
        InputStream in = socket.getInputStream();
        in.read(authResp);
        System.out.println(String.format("auth result: %s", new String(authResp)));
    }

	/**   set   */
    private void set(String key, String value) throws IOException {
        StringBuffer setSb = new StringBuffer();
        setSb.append("*3").append(lineSeparator);
        setSb.append("$3").append(lineSeparator);
        setSb.append("set").append(lineSeparator);
        setSb.append("$").append(key.getBytes().length).append(lineSeparator);
        setSb.append(key).append(lineSeparator);
        setSb.append("$").append(value.getBytes().length).append(lineSeparator);
        setSb.append(value).append(lineSeparator);

        OutputStream out = socket.getOutputStream();
        out.write(setSb.toString().getBytes());
        out.flush();
        byte[] setResp = new byte[1024];
        InputStream in = socket.getInputStream();
        in.read(setResp);
        System.out.println(String.format("set resp: %s", new String(setResp)));
    }
	/**   set   */
    private String get(String key) throws IOException {
        StringBuffer getSb = new StringBuffer();
        getSb.append("*2").append(lineSeparator);
        getSb.append("$3").append(lineSeparator);
        getSb.append("get").append(lineSeparator);
        getSb.append("$").append(key.getBytes().length).append(lineSeparator);
        getSb.append(key).append(lineSeparator);

        OutputStream out = socket.getOutputStream();
        out.write(getSb.toString().getBytes());
        out.flush();
        InputStream in = socket.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        reader.readLine();
        return reader.readLine();
    }

    public static void main(String[] args) throws IOException {
        /*System.getProperties().forEach((k, v) -> {
            System.out.println(k + ":" + v);
        });*/
        TestResp resp = new TestResp("127.0.0.1", 6379);
        resp.auth("redis5");
        resp.set("name","moon");
        System.out.println(String.format("get result: %s", resp.get("name")));
    }
}

以上java socketを用いてredis基本操作コマンド:auth,set,getを実現し,他のコマンドは類似している.