You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

273 lines
6.3 KiB
Go

4 weeks ago
package routers
import (
"flx/controller"
"flx/middleware"
"net/http"
"strconv"
"strings"
"time"
"flx/controller/congresscontrol"
"github.com/gin-gonic/gin"
"github.com/juju/ratelimit"
log "github.com/sirupsen/logrus"
)
func InitRouter(engine *gin.Engine) *gin.Engine {
defer func() {
if r := recover(); r != nil {
log.Error("InitRouter:", r)
}
}()
//注意 Recover 要尽量放在第一个被加载
//如不是的话在recover前的中间件或路由将不能被拦截到
//程序的原理是:
//1.请求进来执行recover
//2.程序异常抛出panic
//3.panic被 recover捕获返回异常信息并Abort,终止这次请求
engine.Use(middleware.Cors())
//http://localhost:9998/static/static/master.644a85b4.jpg
//http://localhost:9998/webs/upload/111.png
//http://localhost:9998/webs/screen/web/meetingview.html
engine.StaticFS("/webs", http.Dir("public"))
engine.Use(middleware.Recover)
// engine.Use(middleware.JwtVerify) //权限验证中间件
engine.GET("/screen/web/meetingview.html", controller.WsIndexs)
resourceRouter(engine)
group := engine.Group("/vhwcapi/v1")
{
groupRouter(group) // 服务分组接口
customizeRouter(group) // 自定义服务接口
websocketRouter(group)
}
// 解决刷新404问题
engine.NoRoute(controller.RedirectIndex)
return engine
}
// resourceRouter 静态资源配置
func resourceRouter(engine *gin.Engine) {
defer func() {
if r := recover(); r != nil {
log.Error("resourceRouter:", r)
}
}()
group := engine.Group("/hucb/hygl") //首页根路径上下文http://localhost:9998/welcome
{
group.GET("", controller.Index)
}
}
func timedHandler(duration time.Duration) func(c *gin.Context) {
defer func() {
if r := recover(); r != nil {
log.Error("timedHandler:", r)
}
}()
return func(c *gin.Context) {
// get the underlying request context
ctx := c.Request.Context()
// create the response data type to use as a channel type
type responseData struct {
status int
body map[string]interface{}
}
// create a done channel to tell the request it's done
doneChan := make(chan responseData)
// here you put the actual work needed for the request
// and then send the doneChan with the status and body
// to finish the request by writing the response
go func() {
time.Sleep(duration)
doneChan <- responseData{
status: 200,
body: gin.H{"hello": "world"},
}
}()
// non-blocking select on two channels see if the request
// times out or finishes
select {
// if the context is done it timed out or was cancelled
// so don't return anything
case <-ctx.Done():
return
// if the request finished then finish the request by
// writing the response
case res := <-doneChan:
c.JSON(res.status, res.body)
}
}
}
func groupRouter(engine *gin.RouterGroup) {
defer func() {
if r := recover(); r != nil {
log.Error("groupRouter:", r)
}
}()
group := engine.Group("/web/api/service/")
group.POST("congresscontrol/tacitScreen", congresscontrol.TacitScreenForWeb)
}
// customizeRouter 自定义服务相关
func customizeRouter(engine *gin.RouterGroup) {
defer func() {
if r := recover(); r != nil {
log.Error("customizeRouter:", r)
}
}()
/*
customize := controller.NewCustomizeApi()
group := engine.Group("customize")
{
group.POST("list", customize.ServerList)
group.GET("running", customize.Run)
group.POST("add", customize.Create)
group.GET("delete", customize.Delete)
}
*/
}
func websocketRouter(engine *gin.RouterGroup) {
defer func() {
if r := recover(); r != nil {
log.Error("websocketRouter:", r)
}
}()
group := engine.Group("/websocket/")
{
group.GET("ccuwebsocket", controller.WsPage) //升级http 协议到 WebSocket
}
}
func rateLimitMiddleware(bucket *ratelimit.Bucket) gin.HandlerFunc {
defer func() {
if r := recover(); r != nil {
log.Error("rateLimitMiddleware:", r)
}
}()
return func(c *gin.Context) {
// 处理请求的前置逻辑
c.Next()
var contentLength int64 = 0
parameterMap := make(map[string]interface{})
controller.DecodeJsonPayload(c, &parameterMap)
if parameterMap["Range"] != nil {
rangeParts := strings.Split(strings.TrimPrefix(parameterMap["Range"].(string), "bytes="), "-")
start, _ := strconv.ParseInt(rangeParts[0], 10, 64)
var end int64 = 0
if len(rangeParts) > 1 && rangeParts[1] != "" {
end, _ = strconv.ParseInt(rangeParts[1], 10, 64)
}
contentLength = end - start
if contentLength < 0 {
contentLength = 0
}
}
// 动态消耗令牌
if bucket.TakeAvailable(contentLength) == 0 {
c.AbortWithStatus(http.StatusTooManyRequests)
return
}
}
}
// // package main
// // import (
// // "net/http"
// // "time"
// // "github.com/gin-gonic/gin"
// // )
// // 创建一个流量限制器中间件限制每秒最大传输量为200MB
// func bandwidthLimiterMiddleware(limit int64) gin.HandlerFunc {
// return func(c *gin.Context) {
// // 创建一个带有流量统计功能的 ResponseWriter
// bw := &bandwidthWriter{
// ResponseWriter: c.Writer,
// limit: limit,
// startTime: time.Now(),
// }
// c.Writer = bw
// // 执行请求
// c.Next()
// // 检查流量限制
// if bw.exceededLimit() {
// c.AbortWithStatus(http.StatusTooManyRequests) // 超过流量限制返回429状态码
// }
// }
// }
// // 自定义 ResponseWriter用于统计流量
// type bandwidthWriter struct {
// gin.ResponseWriter
// bytesWritten int64
// limit int64
// startTime time.Time
// }
// func (bw *bandwidthWriter) Write(data []byte) (int, error) {
// // 统计写入的数据量
// n, err := bw.ResponseWriter.Write(data)
// bw.bytesWritten += int64(n)
// return n, err
// }
// // 判断是否超过流量限制
// func (bw *bandwidthWriter) exceededLimit() bool {
// elapsed := time.Since(bw.startTime).Seconds()
// if int64(elapsed) > 0 {
// currentRate := bw.bytesWritten / int64(elapsed) // 计算当前的传输速率
// return currentRate > bw.limit
// }
// return false
// }
// // func main() {
// // r := gin.Default()
// // // 将流量限制中间件应用到 /download 路由
// // r.GET("/download", bandwidthLimiterMiddleware(200*1024*1024), func(c *gin.Context) {
// // // 模拟大文件下载
// // c.File("largefile.zip")
// // })
// // r.Run(":8080")
// // }