当前位置 博文首页 > go语言实现的memcache协议服务的方法

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

    作者:小囧 时间:2021-02-15 18:31

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

    js
    下一篇:没有了