当前位置: 首页 > 后端技术 > PHP

使用Go学习Redis通信协议

时间:2023-03-29 19:47:19 PHP

鍘熸枃鍦板潃锛氫娇鐢℅o瀛︿範Redis閫氫俊鍗忚Go銆丳HP銆丣ava鈥︹€︽湁閭d箞澶氬寘鏀寔浣犱娇鐢≧edis锛屼綘鏈夋病鏈夋兂杩囨嫢鏈夋湇鍔★紵涓庡鎴风锛屼粬浠浣曟矡閫氾紝浠栦滑浣跨敤浠€涔堥€氫俊鍗忚杩涜浜や簰锛熷熀浜庢垜浠殑鐩殑锛屾湰鏂囦富瑕佽瑙e拰瀹炶返Redis鐨勯€氫俊鍗忚銆俁edis鐨勫鎴风鍜屾湇鍔″櫒閫氳繃TCP杩炴帴浜ゆ崲鏁版嵁銆傛湇鍔$榛樿绔彛鍙蜂负6379锛屽鎴风鍜屾湇鍔$鍙戦€佺殑鍛戒护鎴栨暟鎹兘鏄互\寮€澶寸殑r\n锛圕RLF锛夌粨灏撅紙杩欐槸绾﹀畾淇楁垚锛夊崗璁湪Redis涓垎涓簉equest鍜宺eply锛岃姹傚崗璁垎涓烘柊鐗堟湰鍜屾棫鐗堟湰銆傛柊鐗堟湰鐨勭粺涓€璇锋眰鍗忚鍦≧edis1.2鐗堟湰寮曞叆锛屾渶缁堟垚涓篟edis2.0鐗堟湰銆俁edis鏈嶅姟鍣ㄩ€氫俊鐨勬爣鍑嗘柟寮忔湰鏂囨槸鍩轰簬鏂扮増鏈殑鍗忚瀹炵幇鍔熻兘锛屼笉寤鸿浣跨敤鏃х増鏈紙1.2姣旇緝鑰侊級銆傛柊鍗忚鐨勫悇绉嶇ず渚嬪涓嬶細璇锋眰鍗忚1锛屾牸寮忕ず渚?<鍙傛暟鏁伴噺>CRLF$<鍙傛暟1鐨勫瓧鑺傛暟>CRLF<鍙傛暟1鐨勬暟鎹?CRLF...$<鍙傛暟1鐨勫瓧鏁皃arameterNNumberofsections>CRLFCRLF鍦ㄨ繖涓崗璁笅锛屾墍鏈夊彂閫佺粰Redis鏈嶅姟鍣ㄧ殑鍙傛暟閮芥槸浜岃繘鍒跺畨鍏ㄧ殑锛坆inarysafe锛?.鎵撳嵃渚嬪瓙*3$3SET$5mykey$7myvalue3銆侫ctualprotocolvalue"*3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$7\r\nmyvalue\r\n"杩欐槸Redis鐨勮姹傚崗璁鑼冿紝鍐欏鎴风鎸夌収渚?鐨勯€昏緫锛屾渶鍚庡彂閫佷緥3銆傛垜鐩镐俊浣犲凡缁忔湁浜嗕竴涓ぇ姒傜殑鎯虫硶銆俁edis鍗忚闈炲父绠€娲佹槗鎳傘€傝繖涔熸槸瀹冨鏄撲笂鎵嬬殑鍘熷洜涔嬩竴銆備綘鍙互鎯虫兂杩欐牱瀹氫箟鍗忚鐨勫ソ澶勬槸浠€涔堬紵ReplyRedis浼氭牴鎹綘璇锋眰鐨勫崗璁笉鍚岋紝杩斿洖涓嶅悓绫诲瀷鐨勫洖澶嶏紙鎵ц鍛戒护鐨勭粨鏋滀篃涓嶅悓锛夈€傚湪杩欎釜鍥炲鈥滃崗璁€濅腑锛屽彲浠ラ€氳繃妫€鏌ョ涓€涓瓧鑺傛潵鍒ゆ柇鏄粈涔堢被鍨嬬殑鍥炲锛屽涓嬶細鐘舵€佸洖澶嶏紙statusreply锛夌殑绗竴涓瓧鑺傛槸鈥?鈥濋敊璇洖澶嶏紙errorreply锛夌殑绗竴涓瓧鑺備竴涓瓧鑺傛槸鈥?鈥濇暣鏁板洖澶嶇殑绗竴涓瓧鑺傛槸鈥滐細鈥濇壒閲忓洖澶嶇殑绗竴涓瓧鑺傛槸鈥?鈥濆浜庡鎵归噺鍥炲绗竴涓瓧鑺傛槸鈥?鈥濆洖澶嶇殑鏍囬鍜孋RLF鍦ㄦ渶鍚庯紝浣犲彲浠ュぇ鑷寸寽鍑哄洖澶嶇殑鈥滃崗璁€濇槸浠€涔堬紝浣嗙湡鐩稿彧鑳介€氳繃瀹炶返鏉ヨ幏寰椼€傛垜鐭ラ亾浣犲緢蹇氨浼氬繕璁梆煒€缁冧範涓嶳edis鏈嶅姟鍣ㄤ氦浜抪ackagemainimport("log""net""os""github.com/EDDYCJY/redis-protocol-example/protocol")const(Address="127.0.0.1:6379"Network="tcp")funcConn(network,addressstring)(net.Conn,error){conn,err:=net.Dial(network,address)iferr!=nil{returnnil,err}returnconn,nil}funcmain(){//璇诲彇杈撳叆args:=os.Args[1:]iflen(args)<=0{log.Fatalf("Os.Args<=0")}//鑾峰彇璇锋眰鍗忚reqCommand:=protocol.GetRequest(args)//杩炴帴鍒癛edis鏈嶅姟鍣╮edisConn,err:=Conn(Network,Address)iferr!=nil{log.Fatalf("Connerr:%v",err)}deferredisConn.Close()//鍐欏叆璇锋眰鍐呭_,err=redisConn.Write(reqCommand)iferr!=nil{log.Fatalf("ConnWriteerr:%v",err)}//璇诲彇鍥炲鍛戒护:=make([]byte,1024)n,err:=redisConn.Read(command)iferr!=nil{log.Fatalf("ConnReaderr:%v",err)}//澶勭悊鍥炲reply,err:=protocol.GetReply(command[:n])iferr!=nil{log.Fatalf("protocol.GetReplyerr:%v",err)}//澶勭悊鍚庣殑鍥炲鍐呭log.Printf("Reply:%v",reply)//鍘熷鍥炲鍐呭log.Printf("Command:%v",string(command[:n]))}鍒拌繖閲屾垜浠氨瀹屾垚浜嗘暣涓猂edis瀹㈡埛绔笌鏈嶅姟绔氦浜掕繃绋嬶紝濡備笅锛?.璇诲彇鍛戒护琛屽弬鏁帮細鑾峰彇鎵ц鐨凴edis鍛戒护2.鑾峰彇璇锋眰鍗忚鍙傛暟3.杩炴帴Redis鏈嶅姟鍣紝鑾峰彇杩炴帴鍙ユ焺4.灏嗚姹傚崗璁弬鏁板啓鍏ヨ繛鎺ワ細鍙戦€佽姹傜殑鍛戒护琛屽弬鏁?.浠庤繛鎺ヨ鍙栬繑鍥炴暟鎹細璇诲彇涓婁竴娆¤姹傜殑鍥炲鏁版嵁6銆佹牴鎹洖澶嶁€滃崗璁€濈殑鍐呭锛屾祦绋嬪洖澶?鐨勬暟鎹泦锛岃緭鍑哄鐞嗗悗鐨勫洖澶嶅唴瀹瑰拰鍘熷鍥炲鍐呭璇锋眰funcGetRequest(args[]string)[]byte{req:=[]string{"*"+strconv.Itoa(len(args)),}for_,arg:=rangeargs{req=append(req,"$"+strconv.Itoa(len(arg)))req=append(req,arg)}str:=瀛楃涓层€傚姞鍏ワ紙璇锋眰锛屸€淺r\n鈥濓級return[]byte(str+"\r\n")}閫氳繃鍒嗘瀽Redis璇锋眰鍗忚锛屽彲浠ュ緱鍒板畠鐨勮鍒欙紝鍏堝姞涓婃爣蹇椾綅锛岃绠楀弬鏁版€绘暟锛岀劧鍚庡惊鐜悎骞跺瓧鑺傛瘡涓弬鏁扮殑ReplyfuncGetReply(reply[]byte)(interface{},error){replyType:=reply[0]switchreplyType{caseStatusReply:returndoStatusReply(reply[1:])caseErrorReply:returndoErrorReply(reply[1:])caseIntegerReply:returndoIntegerReply(reply[1:])caseBulkReply:returndoBulkReply(reply[1:])caseMultiBulkReply:returndoMultiBulkReply(reply[1:])榛樿鍊硷細杩斿洖nil,nil}}funcdoStatusReply(reply[]byte)(string,error){iflen(reply)==3&&reply[1]=='O'&&reply[2]=='K'{returnOkReply,nil}iflen(reply)==5&&reply[1]=='P'&&reply[2]=='O'&&reply[3]=='N'&&reply[4]=='G'{returnPongReply,nil}returnstring(reply),nil}funcdoErrorReply(reply[]byte)(string,error){杩斿洖瀛楃涓?reply),nil}funcdoIntegerReply(reply[]byte)(int,error){pos:=getFlagPos('\r',reply)缁撴灉,err:=strconv.Atoi(string(reply[:pos]))濡傛灉err!=nil{return0,err}returnresult,nil}...杩欓噷鎴戜滑鎶婃墍鏈夌殑鍥炲绫诲瀷閮藉垎鍙戜簡锛屼笉鍚岀殑鍥炲鏍囧織瀵瑰簲涓嶅悓鐨勫鐞嗘柟寮忋€傝繖閲岄渶瑕佹敞鎰忓嚑涓棶棰橈紝濡備笅锛?.褰撹姹傜殑鍊间笉瀛樺湪鏃讹紝浼氫娇鐢ㄧ壒娈婂€?1浣滀负鍥炲銆?.鏈嶅姟鍣ㄥ彂閫佺殑鎵€鏈夊瓧绗︿覆閮戒互CRLF缁撳熬銆?.鍙互鎵归噺鍥炲澶氫釜鎵归噺鍥炲銆傛敞鎰忕悊瑙?.鏃犲唴瀹规渶閲嶈鐨勬槸涓嶅悓鍥炲瑙勫垯鐨勬妸鎺у彲浠ュ府鍔╁ぇ瀹舵洿濂界殑鐞嗚ВRedis璇锋眰鍜屽洖澶嶇殑浜や簰杩囩▼馃憣鎬荤粨鍐欒繖绡囨枃绔犵殑鍘熷洜鏄洜涓虹粡甯稿湪浣跨敤Redis鐨勬椂鍊欙紝浣犲彧鏄娇鐢ㄥ畠銆備綘涓嶇煡閬撳畠鍩轰簬浠€涔堟牱鐨勯€氫俊鍗忚銆傝繖绉嶆劅瑙夊緢涓嶈垝鏈嶃€傞€氳繃鏈枃鐨勮瑙o紝鐩镐俊浣犲Redis瀹㈡埛绔槸濡備綍涓庢湇鍔$杩涜浜や簰鐨勶紝宸茬粡鏈変簡涓€涓ぇ姒傜殑浜嗚В銆傛垜涔熺煡閬撳畠浣跨敤鐨勯€氫俊鍘熺悊锛屽笇鏈涘浣犳湁鎵€甯姪锛佹渶鍚庯紝濡傛灉鎯宠缁嗘煡鐪嬩唬鐮侊紝鍙宠浆椤圭洰鍦板潃锛歨ttps://github.com/EDDYCJY/re...濡傛灉瀵逛綘鏈夊府鍔╋紝璇风偣Star馃憤鍙傝€冮€氳鍗忚