校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > Java Socket實現Redis客戶端的詳細說明

Java Socket實現Redis客戶端的詳細說明

熱門標簽:宿遷便宜外呼系統平臺 山東外呼銷售系統招商 北京400電話辦理收費標準 超呼電話機器人 十堰營銷電銷機器人哪家便宜 鄭州人工智能電銷機器人系統 日本中國地圖標注 貴州電銷卡外呼系統 魔獸2青云地圖標注

Redis是最常見的緩存服務中間件,在java開發中,一般使用 jedis 來實現。

如果不想依賴第三方組件,自己實現一個簡單的redis客戶端工具,該如何實現呢?本文就是介紹這樣一種方法。

Redis的協議非常簡單,而且輸入數據和輸出數據都遵循統一的協議,具體規則參考這里:

http://redisdoc.com/topic/protocol.html

Redis的命令協議:

$參數數量n

$參數1的值的字節數組長度

$參數1的值的字符串表示

$參數2的值的字節數組長度

$參數2的值的字符串表示

...

$參數n的值的字節數組長度

$參數n的值的字符串表示

Redis的返回協議:

1、狀態回復(status reply)的第一個字節是 "+",單行字符串;
2、錯誤回復(error reply)的第一個字節是 "-";
3、整數回復(integer reply)的第一個字節是 ":";
4、批量回復(bulk reply)的第一個字節是 "$";
5、多條批量回復(multi bulk reply)的第一個字節是 "*";
6、所有的命令都是以 \r\n 結尾。

Java代碼說明

針對上述規則,我們用兩個類來實現:

1、SimpleRedisClient類,主要用于發送請求,并讀取響應結果(字符串);

整體比較簡單,稍微復雜點的地方就是讀取流數據,遇到兩種情況就該結束循環,一是返回長度為-1,二是返回字符串以 \r\n 結尾。

如果處理不當,可能會導致 read 阻塞,Socket卡住。

2、SimpleRedisData類,用于解析響應結果,把redis統一協議的字符串,解析為具體的對象。

這部分代碼完全是按照協議規則來實現的,通過一個游標 pos 來向前移動,在移動過程中識別不同格式的數據。

最復雜的是 list 類型的數據,以 * 開頭,后面跟著一個整數,表示列表中所有元素的數量,然后就是每一個列表元素的值,循環解析即可。

package demo;

import java.io.Closeable;
import java.io.IOException;
import java.net.Socket;
import java.util.List;

public class SimpleRedisClient implements Closeable {

    private String host;
    private int port;
    private String auth;
    private Socket socket = null;

    public SimpleRedisClient(String host, int port, String auth) {
        this.host = host;
        this.port = port;
        this.auth = auth;

        try {
            socket = new Socket(this.host, this.port);
            socket.setSoTimeout(8 * 1000);//8秒
        } catch (Exception ex) {
            socket = null;
            ex.printStackTrace();
        }
    }

    public boolean connect() throws IOException {
        if (socket == null || auth == null || auth.length() = 0) {
            return false;
        }
        String response = execute("AUTH", auth);
        if (response == null || response.length() = 0) {
            return false;
        }
        String res = new SimpleRedisData(response).getString();
        return "OK".compareTo(res) == 0;
    }

    @Override
    public void close()  {
        try {
            if (socket != null) {
                socket.shutdownOutput();
                socket.close();
            }
            //System.out.println("closed");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public String getString(String key) {
        if (socket == null || key == null || key.isEmpty()) {
            return null;
        }
        try {
            String response = execute("GET", key);
            return new SimpleRedisData(response).getString();
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public String setString(String key, String value) {
        if (socket == null || key == null || key.isEmpty()) {
            return null;
        }
        try {
            String response = execute("SET", key, value);
            return new SimpleRedisData(response).getString();
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public String deleteKey(String key) throws IOException {
        if (socket == null || key == null || key.isEmpty()) {
            return null;
        }
        String response = execute("DEL", key);
        return new SimpleRedisData(response).getString();
    }

    public ListString> getKeys(String pattern) throws IOException {
        if (socket == null || pattern == null || pattern.isEmpty()) {
            return null;
        }

        String response = execute("KEYS", pattern);
        return new SimpleRedisData(response).getStringList();
    }

    public String execute(String... args) throws IOException {
        if (socket == null || args == null || args.length = 0) {
            return null;
        }

        //System.out.println(StringUtil.join(args, " "));

        StringBuilder request = new StringBuilder();
        request.append("*" + args.length).append("\r\n");//參數的數量

        for (int i = 0; i  args.length; i++) {
            request.append("$" + args[i].getBytes("utf8").length).append("\r\n");//參數的長度
            request.append(args[i]).append("\r\n");//參數的內容
        }

        socket.getOutputStream().write(request.toString().getBytes());
        socket.getOutputStream().flush();

        StringBuilder reply = new StringBuilder();
        int bufSize = 1024;
        while (true) {
            byte[] buf = new byte[bufSize];
            int len = socket.getInputStream().read(buf);
            if (len  0) {
                break;
            }
            String str = new String(buf, 0, len);
            reply.append(str);
            if (str.endsWith("\r\n")) {
                break;
            }
        }

        String response = reply.toString();
        //System.out.println("response: " + response);
        return response;
    }


}
package demo;

import java.util.ArrayList;
import java.util.List;

public class SimpleRedisData {

    public SimpleRedisData(String rawData) {
        this.rawData = rawData;
        //System.out.println(rawData);
    }

    private int pos;
    private String rawData;

    public String getString() {
        if (rawData == null || rawData.length() = 0) {
            return null;
        }
        int i = rawData.indexOf("\r\n", pos);
        if (i = 0) {
            return null;
        }
        char c = rawData.charAt(pos);
        if (c == '+') {
            int from = pos + 1;
            int to = i;
            String v = rawData.substring(from, to);
            pos = to + 2;
            return v;
        } else if (c == '-') {
            int from = pos + 1;
            int to = i;
            String v = rawData.substring(from, to);
            pos = to + 2;
            return v;
        } else if (c == ':') {
            int from = pos + 1;
            int to = i;
            String v = rawData.substring(from, to);
            pos = to + 2;
            return v;
        } else if (c == '$') {
            int from = pos + 1;
            int to = i;
            int bulkSize = Integer.parseInt(rawData.substring(from, to));
            pos = to + 2;

            from = pos;
            to = pos + bulkSize;
            try {
                //$符號后面的數值是指內容的字節長度,而不是字符數量,所以要轉換為二進制字節數組,再取指定長度的數據
                byte[] buf = rawData.substring(from).getBytes("utf-8");
                String v = new String(buf, 0, bulkSize);
                pos = to + 2;
                return v;
            } catch (Exception ex) {
                ex.printStackTrace();
                return null;
            }
        } else {
            return null;
        }
    }

    public ListString> getStringList() {
        if (rawData == null || rawData.length() = 0) {
            return null;
        }
        int i = rawData.indexOf("\r\n", pos);
        if (i = 0) {
            return null;
        }
        char c = rawData.charAt(pos);
        if (c == '*') {
            ListString> values = new ArrayList>();
            int from = pos + 1;
            int to = i;
            int multSize = Integer.parseInt(rawData.substring(from, to));
            pos = to + 2;
            for (int index = 0; index  multSize; index++) {
                values.add(getString());
            }
            return values;
        } else {
            return null;
        }
    }

}
package demo;

import org.junit.jupiter.api.Test;

import java.util.List;

public class RedisTest {

    @Test
    public void test() {
        SimpleRedisClient client = null;
        try {
            client = new SimpleRedisClient("127.0.0.1", 6379, "123456");
            System.out.println("connected: " + client.connect());

            ListString> keyList = client.getKeys("api_*");

            for (int i = 0; i  keyList.size(); i++) {
                System.out.println((i + 1) + "\t" + keyList.get(i));
            }

           System.out.println("keys: " + keyList != null ? keyList.size() : "null");

           System.out.println(client.getString("api_getCustomerName"));

        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (client != null) {
                client.close();
            }
        }
    }

}

優點:

1、不依賴任何第三方組件,可以順利編譯通過;

2、代碼極其簡單。

不足之處:

1、未考慮并發訪問;

2、未提供更多的數據類型,以及讀寫方法,大家可以在此基礎上包裝一下。

以上就是如何用Java Socket實現一個簡單的Redis客戶端的詳細內容,更多關于Java Socket Redis客戶端的資料請關注腳本之家其它相關文章!

您可能感興趣的文章:
  • Java Socket+多線程實現多人聊天室功能
  • Java Socket實現多人聊天系統
  • Java Socket模擬實現聊天室
  • java Nio使用NioSocket客戶端與服務端交互實現方式
  • 淺談java socket的正確關閉姿勢
  • 解決java.net.SocketTimeoutException: Read timed out的問題
  • 詳解Java Socket通信封裝MIna框架
  • Java使用Socket簡單通訊詳解

標簽:北京 朝陽 江蘇 果洛 大慶 臺州 吉安 楊凌

巨人網絡通訊聲明:本文標題《Java Socket實現Redis客戶端的詳細說明》,本文關鍵詞  Java,Socket,實現,Redis,客戶端,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Java Socket實現Redis客戶端的詳細說明》相關的同類信息!
  • 本頁收集關于Java Socket實現Redis客戶端的詳細說明的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    国产精品一区二区在线观看不卡| 欧美在线一二三| 91美女片黄在线观看| 日韩欧美精品三级| 尤物视频一区二区| 丰满少妇久久久久久久| 91精品国产综合久久香蕉麻豆| 中文字幕在线不卡| 国产一区二区毛片| 日韩三区在线观看| 亚洲成人自拍网| 一本一道久久a久久精品| 久久精品亚洲乱码伦伦中文| 午夜激情久久久| 91在线观看视频| 中国av一区二区三区| 激情综合亚洲精品| 日韩一区二区三区在线| 亚洲成人tv网| 欧美日韩国产bt| 午夜伦欧美伦电影理论片| 91首页免费视频| 综合欧美一区二区三区| 白白色亚洲国产精品| 欧美韩国日本不卡| 成人性生交大片免费看中文 | 老司机免费视频一区二区三区| 在线观看三级视频欧美| 一区二区久久久久| 91国内精品野花午夜精品| 亚洲免费在线播放| 在线视频观看一区| 亚洲午夜电影在线| 欧美在线免费播放| 亚洲福利一区二区三区| 欧美日韩和欧美的一区二区| 三级不卡在线观看| 日韩免费视频一区二区| 国产原创一区二区| 国产午夜精品一区二区三区视频 | 日韩主播视频在线| 91精品国产91久久久久久最新毛片 | av网站一区二区三区| 1000部国产精品成人观看| 91免费国产视频网站| 亚洲综合丁香婷婷六月香| 欧美三级韩国三级日本一级| 日韩精品亚洲一区| 久久一日本道色综合| 成人一道本在线| 亚洲精品福利视频网站| 欧美一区二区成人| 国产69精品久久777的优势| 国产精品福利在线播放| 欧美中文字幕一区二区三区亚洲| 丝袜亚洲另类欧美综合| 久久丝袜美腿综合| 99免费精品视频| 日本在线不卡一区| 国产女人18毛片水真多成人如厕 | 亚洲精品成人精品456| 欧美一区二区三区免费在线看| 国精品**一区二区三区在线蜜桃| 亚洲欧洲成人自拍| 91精品国产综合久久精品性色| 国产精品综合久久| 一区二区三区不卡在线观看| 精品久久久久久久久久久院品网| 成人av资源在线观看| 视频一区国产视频| 国产精品色在线观看| 555夜色666亚洲国产免| 大尺度一区二区| 天堂一区二区在线免费观看| 国产精品久久久久久福利一牛影视| 在线视频国内自拍亚洲视频| 国产精品综合av一区二区国产馆| 一区二区三区在线视频免费观看| 26uuu亚洲婷婷狠狠天堂| 一本大道综合伊人精品热热 | 久久久久久99久久久精品网站| 91免费视频观看| 激情偷乱视频一区二区三区| 自拍偷拍国产亚洲| 中文字幕免费一区| 日韩女优av电影| 欧美日韩一卡二卡三卡 | 国产·精品毛片| 蜜乳av一区二区| 亚洲bt欧美bt精品777| 国产精品久久久久久久久晋中 | 色系网站成人免费| 国产a视频精品免费观看| 开心九九激情九九欧美日韩精美视频电影| 国产精品国模大尺度视频| 精品欧美一区二区三区精品久久| 欧美日韩三级一区| 91精品福利视频| 色综合一区二区| 成人深夜视频在线观看| 国产精品亚洲人在线观看| 免费久久99精品国产| 午夜精品久久久久久久久久| 亚洲人成小说网站色在线 | av不卡在线观看| 国产一区二区免费在线| 精品系列免费在线观看| 理论电影国产精品| 蜜桃视频第一区免费观看| 午夜精品视频一区| 午夜不卡av免费| 日韩国产精品久久久久久亚洲| 亚洲综合区在线| 丝袜国产日韩另类美女| 亚洲第一会所有码转帖| 亚洲v日本v欧美v久久精品| 亚洲一二三区在线观看| 亚洲成av人影院| 日韩 欧美一区二区三区| 人人狠狠综合久久亚洲| 水蜜桃久久夜色精品一区的特点| 午夜精品一区二区三区免费视频| 亚洲18影院在线观看| 欧美aaaaa成人免费观看视频| 免费成人在线观看视频| 国产一区在线视频| 粉嫩绯色av一区二区在线观看| 成人av在线影院| 色噜噜狠狠色综合中国| 欧美日韩一二三| 欧美电影免费观看高清完整版在线 | 久久尤物电影视频在线观看| 久久天堂av综合合色蜜桃网| 国产精品久久夜| 亚洲国产美国国产综合一区二区| 首页欧美精品中文字幕| 国产一区二区导航在线播放| 不卡电影一区二区三区| 在线欧美小视频| 日韩一区二区三区三四区视频在线观看 | 91搞黄在线观看| 欧美一区二区视频在线观看 | 欧美日韩中文字幕一区| 日韩一区二区在线播放| 国产日韩在线不卡| 一区二区三区国产| 韩国三级在线一区| 色一情一乱一乱一91av| 日韩精品一区二区三区在线播放| 国产人伦精品一区二区| 亚洲综合色成人| 国产乱码精品1区2区3区| 日本道免费精品一区二区三区| 69av一区二区三区| 国产精品美日韩| 日韩成人免费在线| av一二三不卡影片| 欧美成人video| 亚洲男人都懂的| 国产一区亚洲一区| 91久久精品一区二区| 久久久亚洲精品一区二区三区| 樱花影视一区二区| 国产盗摄女厕一区二区三区 | 欧美大白屁股肥臀xxxxxx| 国产精品久久久99| 看电影不卡的网站| 欧美午夜免费电影| 欧美激情一区在线观看| 日韩电影在线一区| 一本久久综合亚洲鲁鲁五月天 | 韩国在线一区二区| 欧美私模裸体表演在线观看| 国产精品色眯眯| 激情图区综合网| 欧美电影一区二区| 一区二区三区四区激情| 成人深夜福利app| 精品粉嫩aⅴ一区二区三区四区| 亚洲已满18点击进入久久| av网站一区二区三区| 久久精品在线免费观看| 久久精品国产久精国产爱| 久久成人免费网站| 欧美日韩一区二区三区四区五区| 国产精品女上位| 国产麻豆精品久久一二三| 日韩亚洲欧美在线| 午夜精品在线视频一区| 色婷婷久久综合| 国产精品毛片大码女人| 国产成人在线免费| 欧美精品一区二区久久久| 日韩精品91亚洲二区在线观看| 91国产精品成人| 夜夜嗨av一区二区三区网页| 99精品视频在线观看| 中文字幕一区二区5566日韩| 成人深夜视频在线观看| 国产欧美精品在线观看|