This article describes the method of the memcache protocol service implemented by the Go language. Share it for your reference. The details are as follows:
Click here for the full example codeDownload this site。
1. The Go language code is as follows:
Copy the codeThe code is as follows:
package memcachep
import (
"bufio"
"fmt"
"io"
"strconv"
"strings"
)
//mc request generates a request object
type MCRequest struct {
//Request a 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 ("{MCRequest opcode=%s, bodylen=%d, key='%s'}",
, len(), )
}
//Resolve the socket request content into an MCRequest object
func (req *MCRequest) Receive(r *) error {
line, _, err := ()
if err != nil || len(line) == 0 {
return
}
params := (string(line))
command := CommandCode(params[0])
switch command {
case SET, ADD, REPLACE:
= command
= params[1]
, _ = (params[4])
value := make([]byte, +2)
(r, value)
= make([]byte, )
copy(, value)
case GET:
= command
= params[1]
RunStats["cmd_get"].(*CounterStat).Increment(1)
case STATS:
= command
= ""
case DELETE:
= command
= params[1]
}
return err
}
import (
"bufio"
"fmt"
"io"
"strconv"
"strings"
)
//mc request generates a request object
type MCRequest struct {
//Request a 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 ("{MCRequest opcode=%s, bodylen=%d, key='%s'}",
, len(), )
}
//Resolve the socket request content into an MCRequest object
func (req *MCRequest) Receive(r *) error {
line, _, err := ()
if err != nil || len(line) == 0 {
return
}
params := (string(line))
command := CommandCode(params[0])
switch command {
case SET, ADD, REPLACE:
= command
= params[1]
, _ = (params[4])
value := make([]byte, +2)
(r, value)
= make([]byte, )
copy(, value)
case GET:
= command
= params[1]
RunStats["cmd_get"].(*CounterStat).Increment(1)
case STATS:
= command
= ""
case DELETE:
= command
= params[1]
}
return err
}
2. Go language code:
Copy the codeThe code is as follows:
package memcachep
import (
"fmt"
"io"
)
type MCResponse struct {
//Order
Opcoed CommandCode
//Return to status
Status Status
//key
Key string
//Return to content
Value []byte
//Return to the flag
Flags int
//mistake
Fatal bool
}
//Parse the response and write the return result to the socket link
func (res *MCResponse) Transmit(w ) (err error) {
switch {
case STATS:
_, err = ()
case GET:
if == SUCCESS {
rs := ("VALUE %s %d %d\r\n%s\r\nEND\r\n", , , len(), )
_, err = ([]byte(rs))
} else {
_, err = ([]byte(()))
}
case SET, REPLACE:
_, err = ([]byte(()))
case DELETE:
_, err = ([]byte("DELETED\r\n"))
}
return
}
import (
"fmt"
"io"
)
type MCResponse struct {
//Order
Opcoed CommandCode
//Return to status
Status Status
//key
Key string
//Return to content
Value []byte
//Return to the flag
Flags int
//mistake
Fatal bool
}
//Parse the response and write the return result to the socket link
func (res *MCResponse) Transmit(w ) (err error) {
switch {
case STATS:
_, err = ()
case GET:
if == SUCCESS {
rs := ("VALUE %s %d %d\r\n%s\r\nEND\r\n", , , len(), )
_, err = ([]byte(rs))
} else {
_, err = ([]byte(()))
}
case SET, REPLACE:
_, err = ([]byte(()))
case DELETE:
_, err = ([]byte("DELETED\r\n"))
}
return
}
3. The Go language code is as follows:
Copy the codeThe code is as follows:
package memcachep
import (
"fmt"
)
type action func(req *MCRequest, res *MCResponse)
var actions = map[CommandCode]action{
STATS: StatsAction,
}
//Waiting for distribution processing
func waitDispatch(rc chan chanReq) {
for {
input := <-rc
<- dispatch()
}
}
//Distribute the request to the response action operation function
func dispatch(req *MCRequest) (res *MCResponse) {
if h, ok := actions[]; ok {
res = &MCResponse{}
h(req, res)
} else {
return notFound(req)
}
return
}
//The command is not supported
func notFound(req *MCRequest) *MCResponse {
var response MCResponse
= UNKNOWN_COMMAND
return &response
}
//Bind the handler to request binding
func BindAction(opcode CommandCode, h action) {
actions[opcode] = h
}
//stats
func StatsAction(req *MCRequest, res *MCResponse) {
= false
stats := ""
for key, value := range RunStats {
stats += ("STAT %s %s\r\n", key, value)
}
stats += "END\r\n"
= []byte(stats)
}
import (
"fmt"
)
type action func(req *MCRequest, res *MCResponse)
var actions = map[CommandCode]action{
STATS: StatsAction,
}
//Waiting for distribution processing
func waitDispatch(rc chan chanReq) {
for {
input := <-rc
<- dispatch()
}
}
//Distribute the request to the response action operation function
func dispatch(req *MCRequest) (res *MCResponse) {
if h, ok := actions[]; ok {
res = &MCResponse{}
h(req, res)
} else {
return notFound(req)
}
return
}
//The command is not supported
func notFound(req *MCRequest) *MCResponse {
var response MCResponse
= UNKNOWN_COMMAND
return &response
}
//Bind the handler to request binding
func BindAction(opcode CommandCode, h action) {
actions[opcode] = h
}
//stats
func StatsAction(req *MCRequest, res *MCResponse) {
= false
stats := ""
for key, value := range RunStats {
stats += ("STAT %s %s\r\n", key, value)
}
stats += "END\r\n"
= []byte(stats)
}
I hope this article will be helpful to everyone's Go language programming.