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
}
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
}
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)
}
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语言程序设计有所帮助。
上一篇: go语言使用scp的方法实例分析
下一篇: go语言遍历文件夹示例