gin web(http) server

编程入门 行业动态 更新时间:2024-10-27 08:33:14

gin <a href=https://www.elefans.com/category/jswz/34/1770958.html style=web(http) server"/>

gin web(http) server

  • 源代码
package mainimport ("context""database/sql""fmt""log""net/http""os""os/signal""repro_go/gin_webserver/pool""repro_go/gin_webserver/view""time""github.com/gin-gonic/gin"_ "github.com/lib/pq""github.com/redigo-master/redis"
)var redisPtr redis.Conn //redis句柄
var errg error          //全局变量
var pgDB *sql.DB        //pgsql句柄func init() {//若不能打开redis以及pgsql则直接退出//打开redisredisPtr, errg = redis.Dial("tcp", "127.0.0.1:6379") //向本机链接if errg != nil {log.Println(errg)os.Exit(0)}//打开pgsql//用户是postgres 密码 rootpgDB, errg = sql.Open("postgres", "host=localhost port=5432 user=postgres password=root dbname=postgres sslmode=disable")if errg != nil {log.Println(errg)os.Exit(0)}}//Loggeer中间件
func Logger() gin.HandlerFunc { //感觉现在没啥用return func(c *gin.Context) {t := time.Now()// 设置 example 变量c.Set("example", "12345")// 请求前c.Next()// 请求后latency := time.Since(t)log.Print(latency)// 获取发送的 statusstatus := c.Writer.Status()log.Println(status)}
}
func main() {//日志写入文件+控制台// gin.DisableConsoleColor()// f, _ := os.Create("/gin.log")// gin.DefaultWriter = io.MultiWriter(f, os.Stdout)//新建中间件r := gin.New() //r := gin.Default() //使用默认中间件r.Use(Logger())r.LoadHTMLGlob("../view/*") //载入html//静态文件r.StaticFile("/favicon.png", "./static/zu.png")//GET /r.GET("/", func(c *gin.Context) {c.HTML(http.StatusOK, "view/root.htm", gin.H{"doc":    "Hello gin","status": http.StatusOK,})})//GET pingr.GET("/ping", func(c *gin.Context) {c.JSON(200, gin.H{"message": "pong",})})//设置 获取 Cookier.GET("/cookie", func(c *gin.Context) {cookie, err := c.Cookie("gin_cookie")if err != nil {cookie = "NotSet"c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)}fmt.Printf("Cookie value is : %v\n", cookie)})//GET 匹配 /user/jojo/olar.GET("/user/:name/*action", func(c *gin.Context) {name := c.Param("name")action := c.Param("action")message := name + " is " + actionc.String(http.StatusOK, message)})//GET 匹配 /welcome?firstname=jojo&lastname=DIOr.GET("/welcome", func(c *gin.Context) {firstname := c.DefaultQuery("firstname", "Guest")lastname := c.Query("lastname") // 是 c.Request.URL.Query().Get("lastname") 的简写c.String(http.StatusOK, "Hello %v : %v", firstname, lastname)})//上传多文件r.MaxMultipartMemory = 8 << 20 //最大 8 MBr.POST("/upload", func(c *gin.Context) {cCp := c.Copy() //并发 必须使用副本go func() {form, _ := cCp.MultipartForm()files := form.File["upload[]"]for _, file := range files {log.Println(file.Filename)//写入文件fileName := "D:\\#test/" + file.Filename //配置路径if err := cCp.SaveUploadedFile(file, fileName); err != nil {c.String(http.StatusBadRequest, fmt.Sprintf("upload file err: %s", err.Error()))log.Println(err)}}cCp.String(http.StatusOK, "%d files uploaded!", len(files))}()})//http重定向r.GET("/test", func(c *gin.Context) {c.Redirect(http.StatusMovedPermanently, "/")})//路由重定向r.GET("/test1", func(c *gin.Context) {c.Request.URL.Path = "/test2"r.HandleContext(c)})r.GET("/test2", func(c *gin.Context) {c.JSON(200, gin.H{"hello": "world"})})//查询数据库r.GET("/query", func(c *gin.Context) {c.HTML(http.StatusOK, "view/query.htm", gin.H{"doc": "Hello gin",})})r.POST("/query", func(c *gin.Context) {mm := make(map[string]string)sqlcontent := `select  "name","password" from public.stu `row, err := pgDB.Query(sqlcontent)if err != nil {log.Println(err)}for row.Next() {var name stringvar pwd stringerr = row.Scan(&name, &pwd)mm[name] = pwd}c.JSON(http.StatusOK, mm)})// Example for binding a HTML form (user=manu&password=123)//加载html文件r.GET("/login", func(c *gin.Context) {c.HTML(http.StatusOK, "view/login.htm", gin.H{"title": http.StatusOK,})})r.POST("/login", func(c *gin.Context) {var form view.Login// This will infer what binder to use depending on the content-type header.if err := c.ShouldBind(&form); err != nil {/*c.ShouldBindBodyWith 会在绑定之前将 body 存储到上下文中。 这会对性能造成轻微影响,如果调用一次就能完成绑定的话,那就不要用这个方法*/c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}online, _ := UserOnline(form.User)if !online { //redis中没有该用户/*pgsql注册1.已存在 直接redis添加id2.不存在 pgsql添加用户id redis添加id*///1.已存在 直接redis添加//线程池//初始化task结构体var ms pool.Myservicems = formjob := pool.Job{Ms: ms, PGSQLPointer: pgDB}pool.Buff <- job //工作加入线程池// sqlcontent := `select  "name" from public.stu where name=` + form.User// row := pgDB.QueryRow(sqlcontent)// err := row.Scan(&name)// if err != nil {// 	//2.name不存在于pgsql// 	// pgsql添加用户name  redis添加name// 	sqlcontent = `insert into public.stu (name,password) values ($1,$2)`// 	stmt, err := pgDB.Prepare(sqlcontent)// 	_, err = stmt.Exec(form.User, form.Password)// 	if err != nil {// 		//status = "add user error"// 		log.Println(err)// 	}// }redisPtr.Do("SADD", "sessionID", form.User)//重定向//暂时先返回主页c.Redirect(http.StatusMovedPermanently, "http://localhost:8080/")//c.JSON(http.StatusUnauthorized, gin.H{"status": status})return}//暂时先返回主页c.Redirect(http.StatusMovedPermanently, "http://localhost:8080/")//c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})})//优雅的关闭服务器srv := &http.Server{Addr:    ":8080",Handler: r,}go func() {// 服务连接if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {log.Fatalf("listen: %s\n", err)}}()quit := make(chan os.Signal)signal.Notify(quit, os.Interrupt)<-quitlog.Println("Shutdown Server ...")ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)//关闭所有句柄defer cancel()defer redisPtr.Close()defer pgDB.Close()if err := srv.Shutdown(ctx); err != nil {log.Fatal("Server Shutdown:", err)}log.Println("Server exiting")//r.Run() // listen and serve on 0.0.0.0:8080
}//UserOnline... 用户是否在redis缓存中
func UserOnline(username string) (online bool, err error) {id, err := redisPtr.Do("SISMEMBER", "sessionID", username)if id.(int64) == 0 { //用户不在线return false, err}return true, err
}

更多推荐

gin web(http) server

本文发布于:2023-07-28 16:29:37,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1250215.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:web   gin   server   http

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!