您好,登錄后才能下訂單哦!
這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)go語言中怎么實現(xiàn)一個memcache協(xié)議服務(wù),文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
1. Go語言代碼如下:
package memcachep import ( "bufio" "fmt" "io" "strconv" "strings" ) //mc請求產(chǎn)生一個request對象 type MCRequest struct { //請求命令 Opcode CommandCode //key Key string //請求內(nèi)容 Value []byte //請求標(biāo)識 Flags int //請求內(nèi)容長度 Length int //過期時間 Expires int64 } //request to string func (req *MCRequest) String() string { return fmt.Sprintf("{MCRequest opcode=%s, bodylen=%d, key='%s'}", req.Opcode, len(req.Value), req.Key) } //將socket請求內(nèi)容 解析為一個MCRequest對象 func (req *MCRequest) Receive(r *bufio.Reader) error { line, _, err := r.ReadLine() if err != nil || len(line) == 0 { return io.EOF } params := strings.Fields(string(line)) command := CommandCode(params[0]) switch command { case SET, ADD, REPLACE: req.Opcode = command req.Key = params[1] req.Length, _ = strconv.Atoi(params[4]) value := make([]byte, req.Length+2) io.ReadFull(r, value) req.Value = make([]byte, req.Length) copy(req.Value, value) case GET: req.Opcode = command req.Key = params[1] RunStats["cmd_get"].(*CounterStat).Increment(1) case STATS: req.Opcode = command req.Key = "" case DELETE: req.Opcode = command req.Key = params[1] } return err }
2. Go語言代碼:
package memcachep import ( "fmt" "io" ) type MCResponse struct { //命令 Opcoed CommandCode //返回狀態(tài) Status Status //key Key string //返回內(nèi)容 Value []byte //返回標(biāo)識 Flags int //錯誤 Fatal bool } //解析response 并把返回結(jié)果寫入socket鏈接 func (res *MCResponse) Transmit(w io.Writer) (err error) { switch res.Opcoed { case STATS: _, err = w.Write(res.Value) case GET: if res.Status == SUCCESS { rs := fmt.Sprintf("VALUE %s %d %d\r\n%s\r\nEND\r\n", res.Key, res.Flags, len(res.Value), res.Value) _, err = w.Write([]byte(rs)) } else { _, err = w.Write([]byte(res.Status.ToString())) } case SET, REPLACE: _, err = w.Write([]byte(res.Status.ToString())) case DELETE: _, err = w.Write([]byte("DELETED\r\n")) } return }
3. Go語言代碼如下:
package memcachep import ( "fmt" ) type action func(req *MCRequest, res *MCResponse) var actions = map[CommandCode]action{ STATS: StatsAction, } //等待分發(fā)處理 func waitDispatch(rc chan chanReq) { for { input := <-rc input.response <- dispatch(input.request) } } //分發(fā)請求到響應(yīng)的action操作函數(shù)上去 func dispatch(req *MCRequest) (res *MCResponse) { if h, ok := actions[req.Opcode]; ok { res = &MCResponse{} h(req, res) } else { return notFound(req) } return } //未支持命令 func notFound(req *MCRequest) *MCResponse { var response MCResponse response.Status = UNKNOWN_COMMAND return &response } //給request綁定上處理程序 func BindAction(opcode CommandCode, h action) { actions[opcode] = h } //stats func StatsAction(req *MCRequest, res *MCResponse) { res.Fatal = false stats := "" for key, value := range RunStats { stats += fmt.Sprintf("STAT %s %s\r\n", key, value) } stats += "END\r\n" res.Value = []byte(stats) }
上述就是小編為大家分享的go語言中怎么實現(xiàn)一個memcache協(xié)議服務(wù)了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。