• sqler sql 转rest api 源码解析(二) resp 协议


    resp 协议主要是方便使用redis 客户端进行连接,resp 主要是依赖 tidwall/redcon golang redis 协议包

    resp 服务说明

    server_resp.go 文件,干的事情比较简单,就是redis command 的支持,包含了几个内置的
    ping select help quit echo, 以及宏相关的list 以及宏调用的command

    代码

    server_resp.go

    • 注册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 方便,返回宏的列表

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

    宏方便指定
    核心是commandExecMacro

     
    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 方法如下:

    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.go

  • 相关阅读:
    VUE DEVTOOLS 安装方法(npm cnpm 安装失败找不到安装工具问题解决方法)
    idea 注释模版
    阿里巴巴编码规范
    JRebel 实现热部署
    SPRING 扩展组件
    oracle 闪回
    ORACLE 日常
    springboot log4j
    支付宝异步回调验证签名的那些走过的坑
    ASP.NET MVC5(一)—— URL路由
  • 原文地址:https://www.cnblogs.com/rongfengliang/p/10268012.html
Copyright © 2020-2023  润新知