设为首页 加入收藏

TOP

GO实现Redis:GO实现Redis协议解析器(2)(一)
2023-07-23 13:31:30 】 浏览:102
Tags:实现 Redis 解析器

  • 本文实现Redis的协议层,协议层负责解析指令,然后将指令交给核心database执行
  • echo database用来测试协议层的代码
  • https://github.com/csgopher/go-redis
  • 本文涉及以下文件:
    conn:定义连接接口
    interface/reply:定义各类响应接口
    consts:定义常用响应
    errors:定义错误响应
    resp/reply:实现reply接口
    parser:解析指令
    conn:实现conn接口
    handler:解析指令再交给database层
    database:定义核心层接口
    echo_database:测试

RESP协议

RESP是客户端与服务端通信的协议,格式有五种:
正常回复:以“+”开头,以“\r\n”结尾的字符串形式
错误回复:以“-”开头,以“\r\n”结尾的字符串形式
整数:以“:”开头,以“\r\n”结尾的字符串形式
多行字符串:以“$”开头,后跟实际发送字节数,再以“\r\n”开头和结尾

$3\r\nabc\r\n

数组:以“*”开头,后跟成员个数

SET key value
*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n

客户端和服务器发送的命令或数据一律以 \r\n (CRLF)作为换行符。

当我们输入*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n这样一串命令,服务端接收到的是如下的命令:
*3\r\n
$3\r\n
SET\r\n
$3\r\n
key\r\n
$5\r\n
value\r\n


interface/resp/conn.go

type Connection interface {
   Write([]byte) error
   GetDBIndex() int
   SelectDB(int)
}

interface/resp/reply.go
type Reply interface {
	ToBytes() []byte
}

Connection接口:Redis客户端的一个连接
Write:给客户端回复消息
GetDBIndex:Redis有16个DB
Reply接口:响应接口


resp/reply/consts.go

type PongReply struct{}

var pongBytes = []byte("+PONG\r\n")

func (r *PongReply) ToBytes() []byte {
    return pongBytes
}

var thePongReply = new(PongReply)

// 回复pong
func MakePongReply() *PongReply { 
    return thePongReply
}

type OkReply struct{}

var okBytes = []byte("+OK\r\n")

func (r *OkReply) ToBytes() []byte {
    return okBytes
}

var theOkReply = new(OkReply)

// 回复ok
func MakeOkReply() *OkReply { 
    return theOkReply
}

var nullBulkBytes = []byte("$-1\r\n")

type NullBulkReply struct{}

func (r *NullBulkReply) ToBytes() []byte {
    return nullBulkBytes
}

// 回复null
func MakeNullBulkReply() *NullBulkReply { 
    return &NullBulkReply{}
}

var emptyMultiBulkBytes = []byte("*0\r\n")

type EmptyMultiBulkReply struct{}

// 回复空数组
func (r *EmptyMultiBulkReply) ToBytes() []byte { 
    return emptyMultiBulkBytes
}

type NoReply struct{}

var noBytes = []byte("")

// 回复空
func (r *NoReply) ToBytes() []byte { 
    return noBytes
}

定义五种回复:回复pong,ok,null,空数组,空

resp/reply/reply.go

type ErrorReply interface {
   Error() string
   ToBytes() []byte
}

ErrorReply:定义错误接口


resp/reply/errors.go

type UnknownErrReply struct{}

var unknownErrBytes = []byte("-Err unknown\r\n")

func (r *UnknownErrReply) ToBytes() []byte {
   return unknownErrBytes
}

func (r *UnknownErrReply) Error() string {
   return "Err unknown"
}

type ArgNumErrReply struct {
   Cmd string
}

func (r *ArgNumErrReply) ToBytes() []byte {
   return []byte("-ERR wrong number of arguments for '" + r.Cmd + "' command\r\n")
}

func (r *ArgNumErrReply) Error() string {
   return "ERR wrong number of arguments for '" + r.Cmd + "' command"
}

func MakeArgNumErrReply(cmd string) *ArgNumErrReply {
   return &ArgNumErrReply{
      Cmd: cmd,
   }
}

type SyntaxErrReply struct{}

var syntaxErrBytes = []byte("-Err syntax error\r\n")
var theSyntaxErrReply = &SyntaxErrReply{}

func MakeSyntaxErrReply() *SyntaxErrReply {
   return theSyntaxErrReply
}

func (r *SyntaxErrReply) ToBytes() []byte {
   return syntaxErrBytes
}

func (r *SyntaxErrReply) Error() string {
   return "Err syntax error"
}

type WrongTypeErrReply struct{}

var wrongTypeErrBytes = []byte("-WRONGTYPE Operation against a key ho
首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇《Go 语言并发之道》读书笔记(七.. 下一篇「Goravel 上新」用户授权模块,..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目