go语言实现的memcache协议服务的方法
本文实例讲述了go语言实现的memcache协议服务的方法。分享给大家供大家参考。具体如下:
完整实例代码点击此处本站下载。
1.Go语言代码如下:
packagememcachep
import(
"bufio"
"fmt"
"io"
"strconv"
"strings"
)
//mc请求产生一个request对象
typeMCRequeststruct{
//请求命令
OpcodeCommandCode
//key
Keystring
//请求内容
Value[]byte
//请求标识
Flagsint
//请求内容长度
Lengthint
//过期时间
Expiresint64
}
//requesttostring
func(req*MCRequest)String()string{
returnfmt.Sprintf("{MCRequestopcode=%s,bodylen=%d,key='%s'}",
req.Opcode,len(req.Value),req.Key)
}
//将socket请求内容解析为一个MCRequest对象
func(req*MCRequest)Receive(r*bufio.Reader)error{
line,_,err:=r.ReadLine()
iferr!=nil||len(line)==0{
returnio.EOF
}
params:=strings.Fields(string(line))
command:=CommandCode(params[0])
switchcommand{
caseSET,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)
caseGET:
req.Opcode=command
req.Key=params[1]
RunStats["cmd_get"].(*CounterStat).Increment(1)
caseSTATS:
req.Opcode=command
req.Key=""
caseDELETE:
req.Opcode=command
req.Key=params[1]
}
returnerr
}2.Go语言代码:
packagememcachep
import(
"fmt"
"io"
)
typeMCResponsestruct{
//命令
OpcoedCommandCode
//返回状态
StatusStatus
//key
Keystring
//返回内容
Value[]byte
//返回标识
Flagsint
//错误
Fatalbool
}
//解析response并把返回结果写入socket链接
func(res*MCResponse)Transmit(wio.Writer)(errerror){
switchres.Opcoed{
caseSTATS:
_,err=w.Write(res.Value)
caseGET:
ifres.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()))
}
caseSET,REPLACE:
_,err=w.Write([]byte(res.Status.ToString()))
caseDELETE:
_,err=w.Write([]byte("DELETED\r\n"))
}
return
}3.Go语言代码如下:
packagememcachep
import(
"fmt"
)
typeactionfunc(req*MCRequest,res*MCResponse)
varactions=map[CommandCode]action{
STATS:StatsAction,
}
//等待分发处理
funcwaitDispatch(rcchanchanReq){
for{
input:=<-rc
input.response<-dispatch(input.request)
}
}
//分发请求到响应的action操作函数上去
funcdispatch(req*MCRequest)(res*MCResponse){
ifh,ok:=actions[req.Opcode];ok{
res=&MCResponse{}
h(req,res)
}else{
returnnotFound(req)
}
return
}
//未支持命令
funcnotFound(req*MCRequest)*MCResponse{
varresponseMCResponse
response.Status=UNKNOWN_COMMAND
return&response
}
//给request绑定上处理程序
funcBindAction(opcodeCommandCode,haction){
actions[opcode]=h
}
//stats
funcStatsAction(req*MCRequest,res*MCResponse){
res.Fatal=false
stats:=""
forkey,value:=rangeRunStats{
stats+=fmt.Sprintf("STAT%s%s\r\n",key,value)
}
stats+="END\r\n"
res.Value=[]byte(stats)
}
希望本文所述对大家的Go语言程序设计有所帮助。