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

sqler sql 转rest api 源码解析(二) resp 协议的更多相关文章

  1. sqler sql 转rest api 源码解析(一)应用的启动入口

    sqler sql 转rest api 的源码还是比较简单的,没有比较复杂的设计,大部分都是基于开源 模块实现的. 说明: 当前的版本为2.0,代码使用go mod 进行包管理,如果本地运行注意gol ...

  2. sqler sql 转rest api 源码解析(四)macro 的执行

    macro 说明 macro 是sqler 的核心,当前的处理流程为授权处理,数据校验,依赖执行(include),聚合处理,数据转换 处理,sql 执行以及sql 参数绑定 授权处理 这个是通过go ...

  3. sqler sql 转rest api 源码解析(三) rest协议

    rest 服务说明 rest 协议主要是将配置文件中的宏暴露为rest 接口,使用了labstack/echo web 框架,同时基于context 模型 进行宏管理对象的共享,同时进行了一些中间件的 ...

  4. Mybatis源码解析(二) —— 加载 Configuration

    Mybatis源码解析(二) -- 加载 Configuration    正如上文所看到的 Configuration 对象保存了所有Mybatis的配置信息,也就是说mybatis-config. ...

  5. RxJava2源码解析(二)

    title: RxJava2源码解析(二) categories: 源码解析 tags: 源码解析 rxJava2 前言 本篇主要解析RxJava的线程切换的原理实现 subscribeOn 首先, ...

  6. Sentinel源码解析二(Slot总览)

    写在前面 本文继续来分析Sentinel的源码,上篇文章对Sentinel的调用过程做了深入分析,主要涉及到了两个概念:插槽链和Node节点.那么接下来我们就根据插槽链的调用关系来依次分析每个插槽(s ...

  7. jQuery 源码解析二:jQuery.fn.extend=jQuery.extend 方法探究

    终于动笔开始 jQuery 源码解析第二篇,写文章还真是有难度,要把自已懂的表述清楚,要让别人听懂真的不是一见易事. 在 jQuery 源码解析一:jQuery 类库整体架构设计解析 一文,大致描述了 ...

  8. Common.Logging源码解析二

    Common.Logging源码解析一分析了LogManager主入口的整个逻辑,其中第二步生成日志实例工厂类接口分析的很模糊,本随笔将会详细讲解整个日志实例工厂类接口的生成过程! (1).关于如何生 ...

  9. erlang下lists模块sort(排序)方法源码解析(二)

    上接erlang下lists模块sort(排序)方法源码解析(一),到目前为止,list列表已经被分割成N个列表,而且每个列表的元素是有序的(从大到小) 下面我们重点来看看mergel和rmergel ...

随机推荐

  1. 五. Python基础(5)--语法

    五. Python基础(5)--语法 1 ● break结束的是它所在的循环体, continue是让它所在的循环体继续循环 # 打印: 1 10 2 10 3 10 4 10 5 10 6 10 7 ...

  2. day 31 udp 协议SOCK_DGRAM

    udp 服务端引用socket=类型,协议绑定地址 和 端口while 循环收到 data addr = 服务.recvfrom(1024)发送 服务.sendto(data,addr(ip 端口)) ...

  3. ubantu 安装mysql 5.7 解决安装不提示设置密码问题

    1.安装Mysql sudo apt-get install mysql-server sudo apt-get install mysql-client sudo apt-get install l ...

  4. freeswitch笔记

    freeswitch知识点:播放录音命令:originate user/1000 &playback(/tmp/123.wav)查看当前注册用户命令:sofia status profile ...

  5. python day09作业答案

    2. def lst(input): lst2=[] count=0 for i in range(0,len(input)): if i %2!=0: lst2.append(input[i]) r ...

  6. python构造IP报文

    import socket import sys import time import struct HOST, PORT = "10.60.66.66", 10086 def m ...

  7. JS之鼠标改变img

    代码用途: 通过点击图片,来改变图片内容 代码: <!DOCTYPE html> <html> <body> <script> function cha ...

  8. Spring Boot 揭秘与实战(一) 快速上手

    文章目录 1. 简介 1.1. 什么是Spring Boot 1.2. 为什么选择Spring Boot 2. 相关知识 2.1. Spring Boot的spring-boot-starter 2. ...

  9. ORACLE外连接实例

    --查询各个部门工资范围,按照1000~2000,2000~3000....这样的格式显示人数 -------------------方法一 select dept.dname ,nvl(ano,) ...

  10. python实现数组和链表的归并排序

    归并排序是一种稳定的排序,采用分而治之策略,可以用于顺序储存结构,也易于在链表上实现.其原理如下图: 算法时间复杂度为  O(nlogn),空间复杂度为 O(n). 1 在数组上实现 def merg ...