Gin开发02

前端之家收集整理的这篇文章主要介绍了Gin开发02前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Gin Web开发02

这章主要解析examples中的Demo。

favicon

解决网站图标问题

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/thinkerou/favicon"
)

func main() {
    app := gin.Default()
    app.Use(favicon.New("./favicon.ico")) // 运行目录下的favicon.ico
    app.GET("/ping",func(c *gin.Context) {
        c.String(200,"Hello favicon.")
    })
    app.Run(":8080")
}

这里引入一个新的库(gin插件),内部处理了/favicon.ico这个URL的返回问题。

basic

模拟了一个DB,然后演示了简单的URL和请求问题。

package main

import (
    "github.com/gin-gonic/gin"
)

var DB = make(map[string]string)

func main() {
    // Disable Console Color
    // gin.DisableConsoleColor()
    r := gin.Default()

    // Ping test
    r.GET("/ping","pong")
    })

    // Get user value
    r.GET("/user/:name",func(c *gin.Context) {
        user := c.Params.ByName("name")
        value,ok := DB[user]
        if ok {
            c.JSON(200,gin.H{"user": user,"value": value})
        } else {
            c.JSON(200,"status": "no value"})
        }
    })

    // Authorized group (uses gin.BasicAuth() middleware)
    // Same than:
    // authorized := r.Group("/")
    // authorized.Use(gin.BasicAuth(gin.Credentials{
    // "foo": "bar",
    // "manu": "123",
    //}))
    authorized := r.Group("/",gin.BasicAuth(gin.Accounts{
        "foo":  "bar",// user:foo password:bar
        "manu": "123",// user:manu password:123
    }))

    authorized.POST("admin",func(c *gin.Context) {
        user := c.MustGet(gin.AuthUserKey).(string)

        // Parse JSON
        var json struct {
            Value string `json:"value" binding:"required"`
        }

        if c.Bind(&json) == nil {
            DB[user] = json.Value
            c.JSON(200,gin.H{"status": "ok"})
        }
    })

    // Listen and Server in 0.0.0.0:8080
    r.Run(":8080")
}
  1. 模拟DB,进行存取操作
  2. 响应/pingURL,给定json返回
  3. 响应有参数/user/:nameURL,并通过c.Params获取URL参数,JSON返回
  4. 使用Group功能,对Url进行namespace管理。还可以统一对Url进行BasicAuth权限管理。
  5. Json数据与Form的绑定,通过c.Bind进行自动解析(Content-Type一定要是Json才有效)。

auto-tls

介绍如何使用TLS协议自动处理连接

package main

import (
    "log"

    "github.com/gin-gonic/autotls"
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()

    // Ping handler
    r.GET("/ping","pong")
    })

    // 方法1
    // log.Fatal(autotls.Run(r,"example1.com","example2.com"))

    // 方法2
    m := autocert.Manager{
        Prompt:     autocert.AcceptTOS,HostPolicy: autocert.HostWhitelist("example1.com","example2.com"),Cache:      autocert.DirCache("/var/www/.cache"),}

    log.Fatal(autotls.RunWithManager(r,&m))
}

app-engine

介绍如何在google appengine中使用。略过。

http2

通过数字证书,使用SSL加密。

package main

import (
    "html/template"
    "log"
    "os"

    "github.com/gin-gonic/gin"
)

var html = template.Must(template.New("https").Parse(` <html> <head> <title>Https Test</title> </head> <body> <h1 style="color:red;">Welcome,Ginner!</h1> </body> </html> `))
func main() {
    logger := log.New(os.Stderr,"", 0)
    logger.Println("[WARNING] DON'T USE THE EMBED CERTS FROM THIS EXAMPLE IN PRODUCTION ENVIRONMENT,GENERATE YOUR OWN!")

    r := gin.Default()
    r.SetHTMLTemplate(html)

    r.GET("/welcome",func(c *gin.Context) {
        c.HTML(200,"https",gin.H{
            "status": "success",})
    })

    // Listen and Server in https://127.0.0.1:8080
    r.RunTLS(":8080","./testdata/server.pem","./testdata/server.key")
}

使用RunTLS后,默认使用HTTPS连接。

graceful-shutdown

说明如何可以优雅地关闭服务。基本思路是使用协程和Chann。一般用不上。

upload-file

single

package main

import (
    "fmt"
    "net/http"

    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default()
    router.Static("/","./public")
    router.POST("/upload",func(c *gin.Context) {
        name := c.PostForm("name")
        email := c.PostForm("email")

        // Source
        file,err := c.FormFile("file")
        if err != nil {
            c.String(http.StatusBadRequest,fmt.Sprintf("get form err: %s",err.Error()))
            return
        }

        if err := c.SaveUploadedFile(file,file.Filename); err != nil {
            c.String(http.StatusBadRequest,fmt.Sprintf("upload file err: %s",err.Error()))
            return
        }

        c.String(http.StatusOK,fmt.Sprintf("File %s uploaded successfully with fields name=%s and email=%s.",file.Filename,name,email))
    })
    router.Run(":8080")
}

展示如何接收文件上传,并且保存到本地。

multiple

package main

import (
    "fmt"
    "net/http"

    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default()
    router.Static("/",func(c *gin.Context) {
        name := c.PostForm("name")
        email := c.PostForm("email")

        // Multipart form
        form,err := c.MultipartForm()
        if err != nil {
            c.String(http.StatusBadRequest,err.Error()))
            return
        }
        files := form.File["files"]

        for _,file := range files {
            if err := c.SaveUploadedFile(file,file.Filename); err != nil {
                c.String(http.StatusBadRequest,err.Error()))
                return
            }
        }

        c.String(http.StatusOK,fmt.Sprintf("Uploaded successfully %d files with fields name=%s and email=%s.",len(files),email))
    })
    router.Run(":8080")
}

展示如何处理多个文件上次功能

realtime-chat

package main

import (
    "fmt"
    "io"
    "math/rand"

    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default()
    router.SetHTMLTemplate(html)

    router.GET("/room/:roomid",roomGET)
    router.POST("/room/:roomid",roomPOST)
    router.DELETE("/room/:roomid",roomDELETE)
    router.GET("/stream/:roomid",stream)

    router.Run(":8080")
}

func stream(c *gin.Context) {
    roomid := c.Param("roomid")
    listener := openListener(roomid)
    defer closeListener(roomid,listener)

    c.Stream(func(w io.Writer) bool {
        c.SSEvent("message",<-listener)
        return true
    })
}

func roomGET(c *gin.Context) {
    roomid := c.Param("roomid")
    userid := fmt.Sprint(rand.Int31())
    c.HTML(200,"chat_room",gin.H{
        "roomid": roomid,"userid": userid,})
}

func roomPOST(c *gin.Context) {
    roomid := c.Param("roomid")
    userid := c.PostForm("user")
    message := c.PostForm("message")
    room(roomid).Submit(userid + ": " + message)

    c.JSON(200,gin.H{
        "status":  "success","message": message,})
}

func roomDELETE(c *gin.Context) {
    roomid := c.Param("roomid")
    deleteBroadcast(roomid)
}

这里只展示main的代码。整个项目思路是:
1. GET /room/:roomid得到一个发送pub的页面,内部调用POST /room/:roomid这个url.
2. GET /stream/:roomid这个建立了Chunck的URL长连接,接收从服务器c.Stream发送过来的数据,没有数据时,等待,直至超时。

其中,服务器使用了window.EventSource机制,在服务端使用c.Stream接口中c.SSEvent来发送event。

realtime-advanced

在realtime-chat的基础上,添加了状态监控,消息列表等展示性质功能

静态文件处理

func main() {
    router := gin.Default()
    router.Static("/assets","./assets")
    router.StaticFS("/more_static",http.Dir("my_file_system"))
    router.StaticFile("/favicon.ico","./resources/favicon.ico")

    // Listen and server on 0.0.0.0:8080
    router.Run(":8080")
}
原文链接:https://www.f2er.com/go/187764.html

猜你在找的Go相关文章