The example in this article describes the approach of the Memcache Protocol service implemented by the go language. Share to everyone for your reference. Specifically as follows:
Full instance code click here to download the site.
1. The go language code is as follows:
Copy Code code as follows:
Package Memcachep
Import (
"Bufio"
"FMT"
"IO"
"StrConv"
"Strings"
)
MC request generates a Request object
Type mcrequest struct {
Request command
Opcode Commandcode
Key
Key string
Request Content
Value []byte
Request identification
Flags int
Request Content Length
Length int
Expiration time
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)
}
Resolves the socket request content to a Mcrequest object
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)
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 Language code:
Copy Code code as follows:
Package Memcachep
Import (
"FMT"
"IO"
)
Type Mcresponse struct {
Command
Opcoed Commandcode
Return status
Status status
Key
Key string
Back to Content
Value []byte
return identification
Flags int
Error
Fatal BOOL
}
Parse response and write the return result to the socket link
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. The go language code is as follows:
Copy Code code as follows:
Package Memcachep
Import (
"FMT"
)
Type action func (req *mcrequest, res *mcresponse)
var actions = map[commandcode]action{
Stats:statsaction,
}
Waiting for distribution to be processed
Func waitdispatch (RC Chan chanreq) {
for {
Input: = <-RC
Input.response <-Dispatch (Input.request)
}
}
To distribute the request to the action action function of the response
Func Dispatch (req *mcrequest) (res *mcresponse) {
If h, OK: = Actions[req. Opcode]; OK {
res = &mcresponse{}
H (req, res)
} else {
Return NotFound (req)
}
Return
}
Command not supported
Func NotFound (req *mcrequest) *mcresponse {
var response mcresponse
Response. Status = Unknown_command
Return &response
}
To bind a handler on a 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)
}
I hope this article will help you with your go language program.