当前位置: 移动技术网 > IT编程>脚本编程>Go语言 > go语言实现的memcache协议服务的方法

go语言实现的memcache协议服务的方法

2017年12月08日  | 移动技术网IT编程  | 我要评论

本文实例讲述了go语言实现的memcache协议服务的方法。分享给大家供大家参考。具体如下:

完整实例代码点击此处。

1. go语言代码如下:

复制代码 代码如下:
package memcachep
import (
    "bufio"
    "fmt"
    "io"
    "strconv"
    "strings"
)
//mc请求产生一个request对象
type mcrequest struct {
    //请求命令
    opcode commandcode
    //key
    key string
    //请求内容
    value []byte
    //请求标识
    flags int
    //请求内容长度
    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请求内容 解析为一个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
    //返回状态
    status status
    //key
    key string
    //返回内容
    value []byte
    //返回标识
    flags int
    //错误
    fatal bool
}
//解析response 并把返回结果写入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,
}
//等待分发处理
func waitdispatch(rc chan chanreq) {
    for {
        input := <-rc
        input.response <- dispatch(input.request)
    }
}
//分发请求到响应的action操作函数上去
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语言程序设计有所帮助。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网