日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

Java Socket實現(xiàn)Redis客戶端的詳細(xì)說明

瀏覽:177日期:2022-08-11 17:30:17

Redis是最常見的緩存服務(wù)中間件,在java開發(fā)中,一般使用 jedis 來實現(xiàn)。

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

Redis的協(xié)議非常簡單,而且輸入數(shù)據(jù)和輸出數(shù)據(jù)都遵循統(tǒng)一的協(xié)議,具體規(guī)則參考這里:

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

Redis的命令協(xié)議:

$參數(shù)數(shù)量n

$參數(shù)1的值的字節(jié)數(shù)組長度

$參數(shù)1的值的字符串表示

$參數(shù)2的值的字節(jié)數(shù)組長度

$參數(shù)2的值的字符串表示

...

$參數(shù)n的值的字節(jié)數(shù)組長度

$參數(shù)n的值的字符串表示

Redis的返回協(xié)議:

1、狀態(tài)回復(fù)(status reply)的第一個字節(jié)是 '+',單行字符串;2、錯誤回復(fù)(error reply)的第一個字節(jié)是 '-';3、整數(shù)回復(fù)(integer reply)的第一個字節(jié)是 ':';4、批量回復(fù)(bulk reply)的第一個字節(jié)是 '$';5、多條批量回復(fù)(multi bulk reply)的第一個字節(jié)是 '*';6、所有的命令都是以 rn 結(jié)尾。

Java代碼說明

針對上述規(guī)則,我們用兩個類來實現(xiàn):

1、SimpleRedisClient類,主要用于發(fā)送請求,并讀取響應(yīng)結(jié)果(字符串);

整體比較簡單,稍微復(fù)雜點的地方就是讀取流數(shù)據(jù),遇到兩種情況就該結(jié)束循環(huán),一是返回長度為-1,二是返回字符串以 rn 結(jié)尾。

如果處理不當(dāng),可能會導(dǎo)致 read 阻塞,Socket卡住。

2、SimpleRedisData類,用于解析響應(yīng)結(jié)果,把redis統(tǒng)一協(xié)議的字符串,解析為具體的對象。

這部分代碼完全是按照協(xié)議規(guī)則來實現(xiàn)的,通過一個游標(biāo) pos 來向前移動,在移動過程中識別不同格式的數(shù)據(jù)。

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

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 List<String> 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('rn');//參數(shù)的數(shù)量for (int i = 0; i < args.length; i++) { request.append('$' + args[i].getBytes('utf8').length).append('rn');//參數(shù)的長度 request.append(args[i]).append('rn');//參數(shù)的內(nèi)容}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('rn')) {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('rn', 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 {//$符號后面的數(shù)值是指內(nèi)容的字節(jié)長度,而不是字符數(shù)量,所以要轉(zhuǎn)換為二進制字節(jié)數(shù)組,再取指定長度的數(shù)據(jù)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 List<String> getStringList() {if (rawData == null || rawData.length() <= 0) { return null;}int i = rawData.indexOf('rn', pos);if (i <= 0) { return null;}char c = rawData.charAt(pos);if (c == ’*’) { List<String> 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()); List<String> 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(); }} }}

優(yōu)點:

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

2、代碼極其簡單。

不足之處:

1、未考慮并發(fā)訪問;

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

以上就是如何用Java Socket實現(xiàn)一個簡單的Redis客戶端的詳細(xì)內(nèi)容,更多關(guān)于Java Socket Redis客戶端的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
中文字幕高清在线播放| 国产一区久久| 中文字幕成人| 色爱综合av| 国产 日韩 欧美一区| 中文字幕在线官网| 日韩精品一级二级| 免费精品视频最新在线| 蜜桃久久久久久| 国产欧美日韩亚洲一区二区三区| 日韩在线观看中文字幕| 国产精品一级| 精品捆绑调教一区二区三区| 99热精品在线观看| 欧美日韩国产免费观看| 中文字幕av亚洲精品一部二部 | 97成人超碰| 久久精品欧洲| 国内精品福利| 日韩高清国产一区在线| 国语对白精品一区二区| 99久久久久国产精品| 香蕉久久久久久| av资源新版天堂在线| 国产日韩专区| 国产精品亚洲产品| 亚洲成人二区| 日本中文字幕不卡| 国产一区三区在线播放| 日韩午夜一区| 精品少妇一区| 日本成人中文字幕| 久久久久91| 麻豆91精品91久久久的内涵| 亚洲国产日韩欧美在线| 欧美精品91| 亚洲欧洲美洲国产香蕉| 欧美日韩在线播放视频| 五月天av在线| 欧美偷窥清纯综合图区| 欧美午夜不卡| 另类专区亚洲| 欧美色综合网| 色8久久久久| 最新亚洲一区| 精品免费av在线| 精品一区二区三区免费看 | 黄色欧美在线| 欧美精品影院| 欧美亚洲一级| 久久国产日韩欧美精品| 丝袜美腿一区二区三区| 美女一区网站| 国产乱子精品一区二区在线观看| 最新日韩欧美| 欧美片第1页综合| 亚洲涩涩av| 五月天激情综合网| 国产99精品一区| 久久免费高清| 亚洲网站视频| 久久激情一区| 亚洲成人精品| 亚洲一区中文| 亚洲美女91| 91亚洲精品视频在线观看| 日本亚洲视频在线| 欧美一区免费| 国产乱子精品一区二区在线观看| 国产精品色在线网站| 欧美国产精品| 国产一区丝袜| 国产精品99一区二区| 久久午夜精品| 69堂精品视频在线播放| 日韩精品欧美大片| 欧美精品aa| 日本精品不卡| 天堂va欧美ⅴa亚洲va一国产| 国产免费久久| 久久精品主播| 亚州av一区| 成人福利av| 视频一区中文字幕| 国产精品a级| 欧美不卡在线| 日本h片久久| 97精品国产福利一区二区三区| 亚洲激情中文在线| 你懂的国产精品永久在线| 久久久久国产精品一区二区| 亚洲影视一区二区三区| 久久久久久久久成人| 欧美专区18| 久久久免费人体| 免费久久99精品国产自在现线| 精品一区二区三区的国产在线观看| 91成人精品| 国产一区二区三区网| 综合干狼人综合首页| 日韩中文在线播放| 亚洲精品高潮| 激情欧美国产欧美| 精品一区二区三区的国产在线观看| 午夜一区在线| 国产精品字幕| 欧美丰满日韩| 国产精品大片免费观看| 免费黄网站欧美| 日韩一区二区三区免费| 欧美91在线| 欧美日韩一区二区高清| 蜜臀av性久久久久蜜臀aⅴ流畅 | 亚洲精品极品少妇16p| 你懂的国产精品永久在线| 深夜福利亚洲| 免播放器亚洲| 亚洲一区二区免费看| 国产一区欧美| 亚洲国产日韩欧美在线| 亚洲福利免费| 在线日韩一区| 婷婷综合社区| 亚洲一区亚洲| 日本亚洲不卡| 最新国产精品视频| 久久国产成人| 免费日韩av| 亚洲2区在线| 国产精品mv在线观看| 久久精品国产一区二区| 久久亚洲黄色| 亚洲播播91| 偷拍欧美精品| 日韩精品欧美大片| 国产精品欧美大片| 精品久久99| 久久精品高清| 久久国产精品99国产| 日韩三级精品| 国产精品一区高清| 国产精品宾馆| 亚洲黄色免费看| 激情欧美日韩一区| 日韩激情综合| 亚洲一区资源| 综合激情网...| 精品欧美日韩精品| 欧美日韩一二三四| 日韩av一二三| 日韩在线欧美| 亚洲欧洲美洲国产香蕉| 久久永久免费| 亚洲在线一区| 国产精品theporn| 亚洲特级毛片| 国产探花在线精品| 欧美日韩视频网站| 日本在线不卡视频| 日韩精品欧美| 国产日产一区| 亚洲欧洲日本mm| 国产一区二区三区探花| 亚洲影院天堂中文av色| 亚洲成av在线| 国产激情综合| 亚洲开心激情| 久久国产亚洲精品| 国产精品久久久久久久久免费高清 | 中文在线а√在线8| 日韩专区一卡二卡| 欧洲一区二区三区精品| 日韩精品久久久久久久软件91| 91精品综合| 久久久男人天堂| 麻豆久久久久久| 亚洲va久久久噜噜噜久久| 成人av三级| 黄色精品视频| 国产精品视频一区二区三区综合 | 日韩在线观看一区二区| 1024精品一区二区三区| 成人在线黄色| 久久影院资源站| 久久av网址| 久久精品天堂| 精品午夜视频| 久久伊人国产| 国产美女亚洲精品7777| 日韩精品中文字幕吗一区二区 | 欧美日韩水蜜桃| 久久久精品午夜少妇| 国产美女高潮在线| 都市激情国产精品| 婷婷激情一区| 伊人成人网在线看| 亚洲高清激情| 日av在线不卡| 日韩福利视频导航| 国产精品高清一区二区|