钉钉事件订阅前缀树算法gin框架解析

当钉钉监测到发生一些事件,如下图

此处举例三个事件user_add_org、user_change_org、user_leave_org,传统的做法是,我们写三个if条件,类似下图

 这样字符串匹配效率比较低,于是联想到gin框架中的路由匹配算法,可以借鉴模仿gin框架的实现方式。 

用实际需求驱动开发,掌握知识的同时还能应用知识,理解得会更加深入。

gin框架源代码解析

gin框架根据路由字符串建树

无论是POST、还是GET底层都是下方代码

func (group *RouterGroup) POST(relativePath string, handlers ...HandlerFunc) IRoutes {return group.handle(http.MethodPost, relativePath, handlers)
}func (group *RouterGroup) handle(httpMethod, relativePath string, handlers HandlersChain) IRoutes {absolutePath := group.calculateAbsolutePath(relativePath)// 把这个新的handlefunc和之前的handlefunc(比如说中间件中的)加在一起handlers = group.combineHandlers(handlers)// 给这个POST请求去建树group.engine.addRoute(httpMethod, absolutePath, handlers)return group.returnObj()
}func (engine *Engine) addRoute(method, path string, handlers HandlersChain) {assert1(path[0] == '/', "path must begin with '/'")assert1(method != "", "HTTP method can not be empty")assert1(len(handlers) > 0, "there must be at least one handler")debugPrintRoute(method, path, handlers)# 取出POST方法的树root := engine.trees.get(method)if root == nil {root = new(node)root.fullPath = "/"engine.trees = append(engine.trees, methodTree{method: method, root: root})}# 具体去建树root.addRoute(path, handlers)
}

树的节点结构如下:

type node struct {path      stringindices   stringwildChild boolnType     nodeTypepriority  uint32children  []*node // child nodes, at most 1 :param style node at the end of the arrayhandlers  HandlersChain // 此处就是对应路径要执行的HandleFuncfullPath  string
}type HandlersChain []HandlerFunctype HandlerFunc func(*Context)

gin框架在请求到来时具体查树执行逻辑

func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {c := engine.pool.Get().(*Context) // 取出一个context对象c.writermem.reset(w)c.Request = reqc.reset()// 关键处理函数engine.handleHTTPRequest(c)engine.pool.Put(c)
}func (engine *Engine) handleHTTPRequest(c *Context) {httpMethod := c.Request.MethodrPath := c.Request.URL.Pathunescape := falseif engine.UseRawPath && len(c.Request.URL.RawPath) > 0 {rPath = c.Request.URL.RawPathunescape = engine.UnescapePathValues}if engine.RemoveExtraSlash {rPath = cleanPath(rPath)}// Find root of the tree for the given HTTP method// 找到对应请求方法的前缀树t := engine.treesfor i, tl := 0, len(t); i < tl; i++ {if t[i].method != httpMethod {continue}root := t[i].root// Find route in tree// 去前缀树中取值value := root.getValue(rPath, c.params, c.skippedNodes, unescape)if value.params != nil {c.Params = *value.params}if value.handlers != nil {// 找到所有的handlerfuncc.handlers = value.handlersc.fullPath = value.fullPath// 具体去执行handlerfuncc.Next()c.writermem.WriteHeaderNow()return}......}
}func (c *Context) Next() {c.index++for c.index < int8(len(c.handlers)) {c.handlers[c.index](c) // 依次调用handlefunc,让c(context)在不同的func中传递c.index++}
}

钉钉事件回调具体实现

方式一:修改gin框架源代码(不推荐修改源代码)

我们第一步是先来建树,并且绑定对应的方法

第二步的话,就是当有钉钉群聊修改了名称,钉钉会给我们发送请求,会执行以下代码

 

 其中,ServeHTTP是当网络请求过来的时候,我们会执行的方法,下面我新添加的两个方法,是当钉钉事件发生的时候,就会执行,然后找到路由树中对应的方法,即可做出对应的逻辑处理。 

问题:

由于在查找树的时候,修改了gin框架的源代码,所以我们提交代码到仓库里面,其他同事是无法使用的,所以我们需要尽量不修改gin的源代码,也就是说查树的时候,不要修改源代码。

方法二:不修改gin框架源代码

把钉钉的事件注册到gin框架的路由中,在收到钉钉的回调请求之后,再自己给自己发送一个请求,然后就可以了,推荐使用这种方法。

方法三:自己实现前缀树

我们也要给树中的节点上面挂上对应的func,就类似于gin框架中

具体实现后续更新,需要用到context,sync.pool....

参考链接:

​​​​​​事件订阅总览 - 钉钉开放平台

基于 Golang 实现前缀树 Trie

gin框架源码解析 | 李文周的博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/795692.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jangow-01-1.0.1 靶机渗透

信息收集部分&#xff1a; 1.nmap存活探测&#xff1a; 2.nmap端口探测&#xff1a; 3.nmap服务探测&#xff1a; 这里应该是21和80端口&#xff0c;&#xff0c;但21需要登陆访问&#xff0c;用不了&#xff0c;问题不大。 web&#xff1a; 页面&#xff1a; 发现RCE: 1.we…

docker容器环境安装记录(MAC M1)(完善中)

0、背景 在MAC M1中搭建商城项目环境时&#xff0c;采用docker统一管理开发工具&#xff0c;期间碰到了许多环境安装问题&#xff0c;做个总结。 1、安装redis 在宿主机新建redis.conf文件运行创建容器命令&#xff0c;进行容器创建、端口映射、文件挂载、以指定配置文件启动…

【SCI绘图】【曲线图系列1 python】绘制扫描点平滑曲线图

SCI&#xff0c;CCF&#xff0c;EI及核心期刊绘图宝典&#xff0c;爆款持续更新&#xff0c;助力科研&#xff01; 本期分享&#xff1a; 【SCI绘图】【曲线图1 python】绘制扫描点平滑曲线图 1.环境准备 python 3 import numpy as np import pandas as pd import proplot …

win10上一个详细的Django开发入门例子

1.Django概述 Django是一个开放源代码的Web应用框架&#xff0c;由Python写成。采用了MTV的框架模式&#xff0c;即模型M&#xff0c;视图V和模版T。 Django 框架的核心组件有&#xff1a; 用于创建模型的对象关系映射&#xff1b; 为最终用户设计较好的管理界面&#xff1b…

使用Arcpy进行数据批处理-批量裁剪

时空大数据使我们面临前所未有的机遇和挑战&#xff0c;尤其在地学、遥感或空间技术等专业领域&#xff0c;无疑是一个全新的时代。 伴随着时空大数据的到来&#xff0c;海量数据的处理是一个所有科研工作者都无法忽视的重要问题。传统的数据&#xff08;主要指空间数据&#x…

Docker实战教程 第1章 Linux快速入门

2-1 Linux介绍 为什么要学Linux 三个不得不学习 课程需要&#xff1a;Docker开发最好在Linux环境下。 开发需要&#xff1a;作为一个后端程序员&#xff0c;是必须要掌握Linux的&#xff0c;这是找工作的基础门槛。 运维需要&#xff1a;在服务器端&#xff0c;主流的大型服…

SDWebImage源码解析---疑难问题解答

SDWebImage的简单流程图&#xff1a; 上图大致流程是对的&#xff0c;有几个没写到的地方&#xff1a; 首先判断url的类型是不是URL类型或string类型&#xff0c;判断url是否为nil占位图更早一些&#xff0c;在url判断后&#xff0c;就行显示占位图加载沙盒中对应的图片后&…

Premiere Pro 2024:赋予创意翅膀,让你的视频飞翔 mac/win版

Premiere Pro 2024&#xff0c;作为Adobe旗下的旗舰视频编辑软件&#xff0c;自推出以来&#xff0c;一直在视频制作领域占据着重要的地位。随着技术的不断进步和创新&#xff0c;Premiere Pro 2024为用户带来了前所未有的编辑体验&#xff0c;重新定义了视频制作的标准。 Pre…

数字逻辑分析仪初体验

为啥会用到这玩意儿&#xff0c;要从一个荒诞的需求开始。想在市面上找一款特别低空飞行的监控&#xff0c;而且不想它一直开着监控&#xff0c;最好是我在外面远程指挥它起飞&#xff0c;飞去厨房&#xff0c;飞去洗手间&#xff0c;甚至飞去阳台&#xff0c;查看水龙头情况啊…

Nuxt 项目的创建

中文文档&#xff1a;https://nuxt.com.cn/docs/getting-started/installation#%E6%96%B0%E9%A1%B9%E7%9B%AE Nuxt 项目创建的先决条件&#xff1a; Node.js 版本 18.0.0 及以上文本编辑器&#xff1a;VS Code Volar 插件 或 Webstorm 执行如下命令&#xff0c;创建 Nuxt 项目…

【Canvas技法】用椭圆绘制经纬线

【图示】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>用椭圆绘制经纬线</title><style type"text/css"…

相对论中关于光速不变理解的补充

近几个月在物理直播间聊爱因斯坦相对论&#xff0c;发现好多人在理解爱因斯坦相对论关于基本假设&#xff0c;普遍认为光速是不变的&#xff0c;质能方程 中光速的光速不变的&#xff0c;在这里我对这个假设需要做一个补充&#xff0c;他是基于质能方程将光速C 在真是光速变化曲…

Allavsoft for Mac v3.27.0.8852注册激活版 优秀的视频下载工具

Allavsoft for Mac是一款功能强大的多媒体下载和转换工具&#xff0c;支持从各种在线视频网站和流媒体服务下载视频、音频和图片。它具备批量下载和转换功能&#xff0c;可将文件转换为多种格式&#xff0c;以适应不同设备的播放需求。此外&#xff0c;Allavsoft还提供视频编辑…

最新版两款不同版SEO超级外链工具PHP源码

可根据个人感觉喜好自行任意选择不同版本使用&#xff08;版V1或版V2&#xff09; 请将zip文件全部解压缩即可访问&#xff01; 源码全部开源&#xff0c;支持上传二级目录访问 #已更新增加大量高质量外链&#xff08;若需要增加修改其他外链请打开txt文件&#xff09; #修…

贪心算法|53.最大子序和

力扣题目链接 class Solution { public:int maxSubArray(vector<int>& nums) {int result INT32_MIN;int count 0;for (int i 0; i < nums.size(); i) {count nums[i];if (count > result) {result count;}if (count < 0) count 0;}return result;} …

SpringBoot+ECharts+Html 字符云/词云案例详解

1. 技术点 SpringBoot、MyBatis、thymeleaf、MySQL、ECharts 等 2. 准备条件 在mysql中创建数据库echartsdb&#xff0c;数据库中创建表t_comment表&#xff0c;表中设置两个字段word与count&#xff0c;添加表中的数据。如&#xff1a;附件中的 echartsdb.sql 3. SpringBoot…

CAD Plant3D 2024 下载地址及安装教程

CAD Plant3D是一款专业的三维工厂设计软件&#xff0c;用于在工业设备和管道设计领域进行建模和绘图。它是Autodesk公司旗下的AutoCAD系列产品之一&#xff0c;专门针对工艺、石油、化工、电力等行业的设计和工程项目。 CAD Plant3D提供了一套丰富的工具和功能&#xff0c;帮助…

水泥5G智能制造工厂数字孪生可视化平台,推进水泥行业数字化转型

水泥5G智能制造工厂数字孪生可视化平台&#xff0c;推进水泥行业数字化转型。水泥5G智能制造工厂数字孪生可视化平台&#xff0c;是水泥行业数字化转型的关键推手。数字孪生平台运用先进的信息技术和数字化手段&#xff0c;实现水泥生产过程的数字化模拟、可视化监控和智能化管…

常见的线程安全类

线程安全&#xff01;线程安全&#xff01;&#xff01;线程安全&#xff01;&#xff01;&#xff01; 鼠鼠我最近被线程安全这个词弄得好烦啊&#xff0c;那既然如此就来写一篇常见的线程安全类防止以后鼠鼠我的大脑又宕机了忘记了....... 这里我们讨论的线程安全的是指&am…

DVWA-File Inclusion通关教程-完结

DVWA-File Inclusion通关教程-完结 文章目录 DVWA-File Inclusion通关教程-完结页面功能LowMediumHighImpossible 页面功能 点击页面上提供的三个页面&#xff0c;单击这些文件就会显示其执行内容&#xff0c;同时发现提交是由GET方式进行&#xff0c;使用page参数传参。 …