sqler sql 轉rest api 源碼解析(二) resp 協議

resp 協議主要是方便使用redis 客戶端進行鏈接,resp 主要是依賴 tidwall/redcon golang redis 協議包git

resp 服務說明

server_resp.go 文件,乾的事情比較簡單,就是redis command 的支持,包含了幾個內置的
ping select help quit echo, 以及宏相關的list 以及宏調用的commandgithub

代碼

server_resp.gogolang

  • 註冊redis 協議服務
 
func initRESPServer() error {
  return redcon.ListenAndServe(
    *flagRESPListenAddr,
    func(conn redcon.Conn, cmd redcon.Command) {
      // handles any panic
      defer (func() {
        if err := recover(); err != nil {
          conn.WriteError(fmt.Sprintf("fatal error: %s", (err.(error)).Error()))
        }
      })()
 
 
  • 協議解析
    內置協議的處理help echo ping 。。。
    比較簡單,就是寫數據,都是字符串類型的
 
// internal command to pick a database
      if todoNormalized == "select" {
        conn.WriteString("OK")
        return
      }
      // internal ping-pong
      if todoNormalized == "ping" {
        conn.WriteString("PONG")
        return
      }
      // ECHO <args ...>
      if todoNormalized == "echo" {
        conn.WriteString(strings.Join(args, " "))
        return
      }
 
 

宏調用
list command 命令,主要是調用macrosManager 的list 方便,返回宏的列表redis

 
// HELP|INFO|LIST
      if todoNormalized == "list" || todoNormalized == "help" || todoNormalized == "info" {
        conn.WriteArray(macrosManager.Size())
        for _, v := range macrosManager.List() {
          conn.WriteBulkString(v)
        }
      }
 
 

宏方便指定
核心是commandExecMacrosql

 
macro := macrosManager.Get(todo)
      if nil == macro {
        conn.WriteError("not found")
        conn.Close()
        return
      }
      var input map[string]interface{}
      if len(args) > 0 {
        json.Unmarshal([]byte(args[0]), &input)
      }
      // handle our command
      commandExecMacro(conn, macro, input)
 
 

commandExecMacro 方法以下:json

func commandExecMacro(conn redcon.Conn, macro *Macro, input map[string]interface{}) {
  // 調用macro 的call,call 包含了宏生命週期中的處理,注意input 數據是一個json 對象數據,因此經過
  redis 客戶端調用宏的時候數據須要json 序列化
  out, err := macro.Call(input)
  if err != nil {
    conn.WriteArray(2)
    conn.WriteInt(0)
    j, _ := json.Marshal(err.Error())
    conn.WriteBulk(j)
    return
  }
  jsonOUT, _ := json.Marshal(out)
  conn.WriteArray(2)
  conn.WriteInt(1)
  conn.WriteBulk(jsonOUT)
}
 
 

參考資料

https://github.com/tidwall/redcon
https://github.com/alash3al/sqler/blob/master/server_resp.goui

相關文章
相關標籤/搜索