欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-05-15 08:17:32
本文实例讲述了go语言实现的memcache协议服务的方法。分享给大家供大家参考。具体如下: 完整实例代码点击此处。 1. go语言代码如下: 复制代码 代码如下:p...

本文实例讲述了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语言程序设计有所帮助。