当前位置: 首页 > wzjs >正文

武汉手机app制作淘宝优化关键词的步骤

武汉手机app制作,淘宝优化关键词的步骤,网站logo设计免费版在线,网页设计与制作课堂革命典型案例本文目录 1. 工作环境准备2. 优雅启停抽取封装 3. 路由4.验证码接口导入redis支持 1. 工作环境准备 在GoProject路径下创建work工作区,依次输入以下命令完成工作目录的构建。 mkdir msproject go work init mkdir project-user cd project-user go mod init test.…

在这里插入图片描述

本文目录

  • 1. 工作环境准备
  • 2. 优雅启停
    • 抽取封装
  • 3. 路由
  • 4.验证码接口
    • 导入redis支持

1. 工作环境准备

GoProject路径下创建work工作区,依次输入以下命令完成工作目录的构建。

mkdir msproject
go work init
mkdir project-user
cd project-user
go mod init test.com/project-user
cd ..
go work use ./project-user

在路径下安装gin框架。

go get -u github.com/gin-gonic/gin

2. 优雅启停

main.go中创建优雅启停的代码,如下所示。

package mainimport ("context""github.com/gin-gonic/gin""log""net/http""os""os/signal""syscall""time"
)func main() {r := gin.Default()srv := &http.Server{Addr:    ":80",Handler: r,}go func() {log.Printf("web server running is %s \n", srv.Addr)if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {log.Fatalln(err)}}()quit := make(chan os.Signal)signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)<-quitlog.Println("shutting down project web server...")ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)defer cancel()if err := srv.Shutdown(ctx); err != nil {log.Fatalln("web server shutdown,cause by:", err)}select {case <-ctx.Done():log.Println("关闭超时")}log.Println("web server stop success...")
}

下面来说明每个代码模块的作用:

	go func() {log.Printf("web server running is %s \n", srv.Addr)if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {log.Fatalln(err)}}()

启动一个 HTTP Web 服务器,并在后台以独立的协程运行。调用 srv.ListenAndServe() 方法,启动服务器并开始监听客户端请求。如果在启动过程中发生错误,并且该错误不是因为服务器被正常关闭(即错误不是 http.ErrServerClosed),则会通过 log.Fatalln 记录错误信息并终止程序运行。整个过程被封装在一个匿名函数中,并通过 go func() 的方式启动为一个独立的协程,这样可以避免阻塞主线程,从而让主线程可以继续执行其他任务,例如处理关闭信号等操作。

	quit := make(chan os.Signal)signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)<-quit

quit := make(chan os.Signal)创建一个信号通道 quit,用于接收操作系统发送的信号。这个通道的类型是 os.Signal,专门用于传递信号事件

signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)使用 signal.Notify 函数将通道 quit 注册到信号监听中,指定监听的信号类型为 syscall.SIGINTsyscall.SIGTERM。SIGINT 是用户通过键盘输入(如 Ctrl+C)发送的中断信号,通常用于请求程序终止。SIGTERM 是一个更通用的终止信号,通常由系统或进程管理工具发送,用于请求程序优雅地关闭。当程序接收到这些信号中的任何一个时,操作系统会将信号发送到 quit 通道。

这是一个阻塞操作,表示从 quit 通道中接收信号。程序会在这里暂停执行,直到通道中接收到一个信号(即程序接收到 SIGINT 或 SIGTERM)一旦接收到信号,程序会继续执行后续的关闭逻辑

也就是说,当程序接收到用户或系统发送的中断或终止信号时,它不会直接退出,而是触发后续的清理操作(如关闭服务器、释放资源等),从而确保程序能够安全地关闭。

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

创建了一个带有超时限制的上下文 ctx,超时时间为 5 秒。context.WithTimeout 函数基于 context.Background() 创建了一个新的上下文,并为其设置了超时时间。如果在 5 秒内没有完成关闭操作,上下文将被取消。defer cancel() 确保在函数返回时调用 cancel() 函数,从而释放与上下文相关的资源,避免资源泄漏

if err := srv.Shutdown(ctx); err != nil {log.Fatalln("web server shutdown, cause by:", err)
}

Shutdown 方法会等待所有正在处理的请求完成,然后关闭服务器。这里的上下文 ctx 用于限制关闭操作的执行时间

	select {case <-ctx.Done():log.Println("wait timeout...")}

回顾一下select语法,其 是 Go 语言中用于同时监听多个通道操作的语法结构。select 语句会阻塞,直到其中一个 case 中的通道操作可以执行(即通道准备好发送或接收数据)。

ctx.Done()context.Context 提供的一个通道,当上下文被取消(cancel() 被调用)或超时(如果设置了超时时间)时,该通道会被关闭。

<-ctx.Done() 表示从 ctx.Done() 通道中接收数据。如果通道被关闭(即上下文被取消或超时),case 会被触发。

运行代码,可以验证所写的功能。

在这里插入图片描述

抽取封装

因为其他模块可能都有用到启停,所以需要把这个模块抽取到公共模块common中去。

创建一个新的common目录,然后编写一个Run文件,并且加入到work工作目录中,D:\GoProject\msproject> go work use ./project-commonRun.go的代码如下。

package commonimport ("context""github.com/gin-gonic/gin""log""net/http""os""os/signal""syscall""time"
)func Run(r *gin.Engine, svrName string, addr string) {srv := &http.Server{Addr:    addr,Handler: r,}go func() {log.Printf("%s running is %s \n", svrName, srv.Addr)if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {log.Fatalln(err)}}()quit := make(chan os.Signal)signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)<-quitlog.Printf("shutting down project %s ... \n", svrName)ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)defer cancel()if err := srv.Shutdown(ctx); err != nil {log.Fatalf("%s shutdown,cause by: %v", svrName, err)}select {case <-ctx.Done():log.Println("wait timeout...")}log.Printf("%s stop success... \n", svrName)
}

这样我们就可以在main.go中直接调用common的run了(这里把common包命名为了srv)。

在这里插入图片描述
这样就可以正常使用了,按下ctrl+c也能够正常启停了。

在这里插入图片描述

3. 路由

各个模块的路由不可能都写在mian函数中,所以需要分摊下去,由各个模块自己去管理对应的路由。

所以这就需要实现接口,然后实现对应的接口即可。

现在讲一下实现思路,首先需要构建项目文件结构如下。

在这里插入图片描述
router.go的代码如下。

package routerimport ("github.com/gin-gonic/gin""test.com/project-user/api/user"
)// Router 接口
type Router interface {Route(r *gin.Engine)
}type RegisterRouter struct {
}func New() *RegisterRouter {return &RegisterRouter{}
}func (*RegisterRouter) Route(ro Router, r *gin.Engine) {ro.Route(r)
}func InitRouter(r *gin.Engine) {rg := New()rg.Route(&user.RouterUser{}, r)
}

user.go代码如下,主要是执行handler,处理请求。

package userimport "github.com/gin-gonic/gin"type HandlerUser struct {
}func (*HandlerUser) getCaptcha(ctx *gin.Context) {ctx.JSON(200, "getCaptcha success")
}

route.go代码如下,主要是实现了对应的Route接口。

package userimport "github.com/gin-gonic/gin"type RouterUser struct {
}func (*RouterUser) Route(r *gin.Engine) {h := &HandlerUser{}r.POST("project/login/getCaptcha", h.getCaptcha)
}

运行后,发送请求,能够正常响应。
在这里插入图片描述
这里画了一个流程图,来表示说明。

在这里插入图片描述

4.验证码接口

我们在 project-common文件夹下创建model.go文件,然后定义返回的Result模型。

package commontype BusinessCode inttype Result struct {Code BusinessCode `json:"code"`Msg  string       `json:"msg"`Data any          `json:"data"`
}func (r *Result) Success(data any) *Result {r.Code = 200r.Msg = "success"r.Data = datareturn r
}func (r *Result) Fail(code BusinessCode, msg string) *Result {r.Code = coder.Msg = msgreturn r
}

然后在user.go中来创建对应的返回代码。

在这里插入图片描述

验证一下接口请求,没问题。

在这里插入图片描述


定义手机号验证的逻辑,在common下编写validata.go代码。

package commonimport "regexp"// VerifyMobile 验证手机合法性
func VerifyMobile(mobile string) bool {if mobile == "" {return false}regular := "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$"reg := regexp.MustCompile(regular)return reg.MatchString(mobile)
}

使用 regexp.MustCompile 将正则表达式编译为一个正则对象 reg。最后,调用 reg.MatchString(mobile) 方法,检查传入的手机号码是否与正则表达式匹配。如果匹配,则返回 true,表示手机号码有效;否则返回 false,表示手机号码无效。

接着我们优化user.go逻辑处理代码,来优化整个登录流程。

func (*HandlerUser) getCaptcha(ctx *gin.Context) {rsp := &common.Result{}//1.获取参数moblie := ctx.PostForm("mobile")//2.校验参数if !common.VerifyMoblie(moblie) {ctx.JSON(http.StatusOK, rsp.Fail(model.NoLegalMoblie, "手机号不合法"))return}//3.生成验证码(随机4位或者6位)code := "123456"//4.调用短信平台(三方,放入go协程中执行,接口可以快速响应,短信几秒到无所谓)go func() {time.Sleep(1 * time.Second)log.Println("短信平台调用成功,发送短信")//5.存储验证码redis,设置过期时间15分钟即可log.Printf("将手机号和验证码存入redis成功:REGISTER %s : %s", moblie, code)}()ctx.JSON(http.StatusOK, rsp.Success(code))
}

在上面我们用到了定义的常量NolegalMoblie,需要创建一个新的文件夹和code.go代码,如下所示。
在这里插入图片描述

导入redis支持

project-user路径下导入redis模块。

go get github.com/go-redis/redis/v8

上面的代码并没有对redis的支持,现在我们需要考虑引用redis了。

但是redis后续可能会缓存在mysql或者mongo或者别的存储器当中,需要不断变换代码,那么就不方便,这个时候就需要用到接口,面向接口编程,低耦合,高内聚。

这里我们进行了如下改动,首先定义了cache的相关接口。

在这里插入图片描述
然后在定义在redis.go中来定义实现的方法
在这里插入图片描述
最后更新user.go中的相关代码即可。

type HandlerUser struct {cache repo.Cache
}func New() *HandlerUser {return &HandlerUser{cache: dao.Rc,}
}func (h *HandlerUser) getCaptcha(ctx *gin.Context) {rsp := &common.Result{}//1.获取参数moblie := ctx.PostForm("mobile")fmt.Println(moblie)//2.校验参数if !common.VerifyMoblie(moblie) {ctx.JSON(http.StatusOK, rsp.Fail(model.NoLegalMoblie, "手机号不合法"))return}//3.生成验证码(随机4位或者6位)code := "123456"//4.调用短信平台(三方,放入go协程中执行,接口可以快速响应,短信几秒到无所谓)go func() {time.Sleep(1 * time.Second)log.Println("短信平台调用成功,发送短信")// redis 假设后续缓存在mysql或者mongo当中,也有可能存储在别的当中// 所以考虑用接口实现,面向接口编程“低耦合,高内聚“// 5.存储验证码redis,设置过期时间15分钟即可c, cancel := context.WithTimeout(context.Background(), 2*time.Second)defer cancel()err := h.cache.Put(c, "REGISTER_"+moblie, code, 15*time.Minute)if err != nil {log.Printf("验证码存入redis出错,causer by :%v\n", err)}log.Printf("将手机号和验证码存入redis成功:REGISTER %s : %s", moblie, code)}()ctx.JSON(http.StatusOK, rsp.Success(code))
}
http://www.dtcms.com/wzjs/280446.html

相关文章:

  • wordpress防黑优化seo
  • 建站软件免费模板合肥网络推广培训学校
  • 深圳建设网站开发水果营销软文
  • 做赌博彩票网站吗网络营销师培训
  • 做移动端网站软件网站推广优化排名seo
  • 学校网站建设目的域名信息查询系统
  • 网站建设dbd3推广方式
  • 北京做网站供应商营销软文500字范文
  • 旅游网站的主要功能seo基础篇
  • pc蛋蛋bc网站开发百度竞价排名平台
  • 做导购网站有哪些贵州网站seo
  • 企业网站建设应该怎么做中国最好的网络营销公司
  • 现在那个网站做视频最赚钱东莞seo建站投放
  • 学校网站建设的意义与途径nba西部排名
  • 做淘宝券推广的网站有哪些软文是什么东西
  • 网站建设公司资质抖音关键词推广怎么做
  • 做网站python好还是javasem培训
  • 广州最专业的网站建设iis搭建网站
  • 如何做商业推广网站厦门百度竞价开户
  • 软件开发培训机构多少钱seo关键词快速提升软件官网
  • 如何开发一个直播平台惠州seo排名收费
  • 网站开网站开发设计公司网络推广网站公司
  • 成都市建设招标网站关键词推广seo怎么优化
  • 费县做网站培训心得体会
  • 做冷库用什么网站发帖子好百度站长工具app
  • 网站版式分类地推拉新app推广怎么做
  • 什么网站是专做代购的企业管理系统
  • 安徽建设学校网站win7优化教程
  • 贵州省建设工程质量检测协会网站电脑系统优化软件排行榜
  • 淘宝客网站制作视频教程免费网站建站平台