go語言實(shí)現(xiàn)的memcache協(xié)議服務(wù)的方法
更新時(shí)間:2015年03月10日 12:17:33 作者:小囧
這篇文章主要介紹了go語言實(shí)現(xiàn)的memcache協(xié)議服務(wù)的方法,實(shí)例分析了Go語言使用memcache的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
本文實(shí)例講述了go語言實(shí)現(xiàn)的memcache協(xié)議服務(wù)的方法。分享給大家供大家參考。具體如下:
完整實(shí)例代碼點(diǎn)擊此處本站下載。
1. Go語言代碼如下:
復(fù)制代碼 代碼如下:
package memcachep
import (
"bufio"
"fmt"
"io"
"strconv"
"strings"
)
//mc請求產(chǎn)生一個(gè)request對象
type MCRequest struct {
//請求命令
Opcode CommandCode
//key
Key string
//請求內(nèi)容
Value []byte
//請求標(biāo)識
Flags int
//請求內(nèi)容長度
Length int
//過期時(shí)間
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)容 解析為一個(gè)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
}
import (
"bufio"
"fmt"
"io"
"strconv"
"strings"
)
//mc請求產(chǎn)生一個(gè)request對象
type MCRequest struct {
//請求命令
Opcode CommandCode
//key
Key string
//請求內(nèi)容
Value []byte
//請求標(biāo)識
Flags int
//請求內(nèi)容長度
Length int
//過期時(shí)間
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)容 解析為一個(gè)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語言代碼:
復(fù)制代碼 代碼如下:
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
//錯(cuò)誤
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
}
import (
"fmt"
"io"
)
type MCResponse struct {
//命令
Opcoed CommandCode
//返回狀態(tài)
Status Status
//key
Key string
//返回內(nèi)容
Value []byte
//返回標(biāo)識
Flags int
//錯(cuò)誤
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語言代碼如下:
復(fù)制代碼 代碼如下:
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)
}
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語言程序設(shè)計(jì)有所幫助。
您可能感興趣的文章:
- golang簡單tls協(xié)議用法完整示例
- GO語言實(shí)現(xiàn)簡單TCP服務(wù)的方法
- Go語言服務(wù)器開發(fā)之簡易TCP客戶端與服務(wù)端實(shí)現(xiàn)方法
- Go語言基于Socket編寫服務(wù)器端與客戶端通信的實(shí)例
- go語言實(shí)現(xiàn)一個(gè)簡單的http客戶端抓取遠(yuǎn)程url的方法
- Go語言服務(wù)器開發(fā)之客戶端向服務(wù)器發(fā)送數(shù)據(jù)并接收返回?cái)?shù)據(jù)的方法
- Golang實(shí)現(xiàn)的聊天程序服務(wù)端和客戶端代碼分享
- golang實(shí)現(xiàn)簡單的udp協(xié)議服務(wù)端與客戶端示例
相關(guān)文章
golang搭建靜態(tài)web服務(wù)器的實(shí)現(xiàn)方法
這篇文章主要介紹了golang搭建靜態(tài)web服務(wù)器的實(shí)現(xiàn)方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08golang中判斷請求是http還是https獲取當(dāng)前訪問地址
這篇文章主要為大家介紹了golang中判斷請求是http還是https獲取當(dāng)前訪問地址示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10go語言錯(cuò)誤處理基本概念(創(chuàng)建返回)
這篇文章主要為大家介紹了go語言錯(cuò)誤處理基本概念(創(chuàng)建返回),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08實(shí)現(xiàn)像php一樣方便的go ORM數(shù)據(jù)庫操作示例詳解
這篇文章主要為大家介紹了實(shí)現(xiàn)像php一樣方便的go ORM數(shù)據(jù)庫操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12