Explorar el Código

feat:ws插件

songzhibin97 hace 3 años
padre
commit
0ea6e7a4ac
Se han modificado 4 ficheros con 167 adiciones y 3 borrados
  1. 27 2
      server/go.mod
  2. 5 1
      server/initialize/plugin.go
  3. 52 0
      server/plugin/ws/utils/utils.go
  4. 83 0
      server/plugin/ws/ws.go

+ 27 - 2
server/go.mod

@@ -3,33 +3,58 @@ module github.com/flipped-aurora/gin-vue-admin/server
 go 1.16
 
 require (
+	github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
 	github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
 	github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible
+	github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
 	github.com/casbin/casbin/v2 v2.11.0
 	github.com/casbin/gorm-adapter/v3 v3.0.2
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
-	github.com/flipped-aurora/gva-plug-email v0.0.0-20210823152517-a061eeea2d16
+	github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
+	github.com/flipped-aurora/ws v1.0.1
 	github.com/fsnotify/fsnotify v1.4.9
 	github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6
 	github.com/gin-gonic/gin v1.6.3
+	github.com/go-ole/go-ole v1.2.4 // indirect
+	github.com/go-openapi/jsonreference v0.19.6 // indirect
+	github.com/go-openapi/spec v0.20.3 // indirect
+	github.com/go-openapi/swag v0.19.15 // indirect
+	github.com/go-playground/validator/v10 v10.3.0 // indirect
 	github.com/go-redis/redis/v8 v8.11.0
 	github.com/go-sql-driver/mysql v1.5.0
 	github.com/gookit/color v1.3.1
+	github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
 	github.com/jordan-wright/email v0.0.0-20200824153738-3f5bafa1cd84
+	github.com/json-iterator/go v1.1.10 // indirect
 	github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible
+	github.com/lestrrat-go/strftime v1.0.3 // indirect
+	github.com/mailru/easyjson v0.7.7 // indirect
+	github.com/mitchellh/mapstructure v1.2.2 // indirect
 	github.com/mojocn/base64Captcha v1.3.1
+	github.com/pelletier/go-toml v1.6.0 // indirect
+	github.com/pkg/errors v0.9.1 // indirect
 	github.com/qiniu/api.v7/v7 v7.4.1
 	github.com/robfig/cron/v3 v3.0.1
 	github.com/satori/go.uuid v1.2.0
 	github.com/shirou/gopsutil v3.21.1+incompatible
+	github.com/spf13/afero v1.2.2 // indirect
+	github.com/spf13/cast v1.3.1 // indirect
+	github.com/spf13/jwalterweatherman v1.1.0 // indirect
+	github.com/spf13/pflag v1.0.5 // indirect
 	github.com/spf13/viper v1.7.0
 	github.com/swaggo/gin-swagger v1.3.0
 	github.com/swaggo/swag v1.7.0
+	github.com/tebeka/strftime v0.1.3 // indirect
 	github.com/tencentyun/cos-go-sdk-v5 v0.7.19
 	github.com/unrolled/secure v1.0.7
 	github.com/xuri/excelize/v2 v2.4.1
-	go.uber.org/zap v1.10.0
+	go.uber.org/zap v1.16.0
 	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
+	golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
+	golang.org/x/tools v0.1.5 // indirect
+	google.golang.org/protobuf v1.24.0 // indirect
+	gopkg.in/ini.v1 v1.55.0 // indirect
 	gorm.io/driver/mysql v1.0.1
 	gorm.io/gorm v1.20.7
+	nhooyr.io/websocket v1.8.6
 )

+ 5 - 1
server/initialize/plugin.go

@@ -2,6 +2,9 @@ package initialize
 
 import (
 	"github.com/flipped-aurora/gin-vue-admin/server/global"
+	"github.com/flipped-aurora/gin-vue-admin/server/plugin/ws"
+	"go.uber.org/zap"
+
 	//email "github.com/flipped-aurora/gva-plug-email"   // 在线仓库模式
 	"github.com/flipped-aurora/gin-vue-admin/server/plugin/email" // 本地插件仓库地址模式
 	"github.com/flipped-aurora/gin-vue-admin/server/plugin/example_plugin"
@@ -18,7 +21,8 @@ func PluginInit(group *gin.RouterGroup, Plugin ...plugin.Plugin) {
 
 func InstallPlugin(PublicGroup *gin.RouterGroup, PrivateGroup *gin.RouterGroup) {
 	//  添加开放权限的插件 示例
-	PluginInit(PublicGroup, example_plugin.ExamplePlugin)
+	PluginInit(PublicGroup, example_plugin.ExamplePlugin, ws.GenerateWs(
+		zap.L(), 100, ws.DefaultCheckMap()))
 
 	//  添加跟角色挂钩权限的插件 示例 本地示例模式于在线仓库模式注意上方的import 可以自行切换 效果相同
 	PluginInit(PrivateGroup, email.CreateEmailPlug(

+ 52 - 0
server/plugin/ws/utils/utils.go

@@ -0,0 +1,52 @@
+package utils
+
+import (
+	"github.com/flipped-aurora/gin-vue-admin/server/global"
+	systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
+	"github.com/gin-gonic/gin"
+	uuid "github.com/satori/go.uuid"
+)
+
+// 从Gin的Context中获取从jwt解析出来的用户ID
+func GetUserID(c *gin.Context) uint {
+	if claims, exists := c.Get("claims"); !exists {
+		global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户ID失败, 请检查路由是否使用jwt中间件!")
+		return 0
+	} else {
+		waitUse := claims.(*systemReq.CustomClaims)
+		return waitUse.ID
+	}
+}
+
+// 从Gin的Context中获取从jwt解析出来的用户UUID
+func GetUserUuid(c *gin.Context) uuid.UUID {
+	if claims, exists := c.Get("claims"); !exists {
+		global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件!")
+		return uuid.UUID{}
+	} else {
+		waitUse := claims.(*systemReq.CustomClaims)
+		return waitUse.UUID
+	}
+}
+
+// 从Gin的Context中获取从jwt解析出来的用户角色id
+func GetUserAuthorityId(c *gin.Context) string {
+	if claims, exists := c.Get("claims"); !exists {
+		global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件!")
+		return ""
+	} else {
+		waitUse := claims.(*systemReq.CustomClaims)
+		return waitUse.AuthorityId
+	}
+}
+
+// 从Gin的Context中获取从jwt解析出来的用户角色id
+func GetUserInfo(c *gin.Context) *systemReq.CustomClaims {
+	if claims, exists := c.Get("claims"); !exists {
+		global.GVA_LOG.Error("从Gin的Context中获取从jwt解析出来的用户UUID失败, 请检查路由是否使用jwt中间件!")
+		return nil
+	} else {
+		waitUse := claims.(*systemReq.CustomClaims)
+		return waitUse
+	}
+}

+ 83 - 0
server/plugin/ws/ws.go

@@ -0,0 +1,83 @@
+package ws
+
+import (
+	"github.com/flipped-aurora/ws/core/biz"
+	"github.com/flipped-aurora/ws/core/data"
+	"github.com/gin-gonic/gin"
+	"go.uber.org/zap"
+	"nhooyr.io/websocket"
+)
+
+type wsPlugin struct {
+	logger               *zap.Logger                       // 日志输出对象
+	manageBuf            int64                             // buffer
+	registeredMsgHandler map[int32]func(biz.IMessage) bool // 消息处理
+	checkMap             map[string]biz.CheckFunc          // 用户校验
+
+	admin     biz.IManage
+	adminCase *biz.AdminCase
+}
+
+func DefaultRegisteredMsgHandler(admin biz.IManage, logger *zap.Logger) map[int32]func(biz.IMessage) bool {
+	return map[int32]func(msg biz.IMessage) bool{
+		1: func(msg biz.IMessage) bool {
+			// w.admin 里面找到注册客户端的方法
+			client, ok := admin.FindClient(msg.GetTo())
+			if !ok {
+				logger.Info("没有找到该用户")
+				return false
+			}
+			return client.SendMes(msg)
+		},
+	}
+}
+
+func DefaultCheckMap() map[string]biz.CheckFunc {
+	return map[string]biz.CheckFunc{
+		"gva_ws": func(c interface{}) (string, bool) {
+			// 先断言是gin.content
+			cc, ok := c.(*gin.Context)
+			if !ok {
+				return "", false
+			}
+			token := cc.Query("jwt")
+			// 可以携带jwt
+			if len(token) == 0 {
+				return "", false
+			}
+			// 解析 jwt...
+
+			return token, true
+		},
+	}
+}
+
+func (w *wsPlugin) Register(g *gin.RouterGroup) {
+	// gva_ws 为身份校验函数
+	g.GET("/ws", w.adminCase.HandlerWS("gva_ws", &websocket.AcceptOptions{
+		InsecureSkipVerify: true,
+	}))
+	g.POST("/sendMsg", w.adminCase.SendMsg("gva_ws"))
+
+}
+
+func (w *wsPlugin) RouterPath() string {
+	return "gva_ws"
+}
+
+func GenerateWs(logger *zap.Logger, manageBuf int64, checkMap map[string]biz.CheckFunc) *wsPlugin {
+	m := data.NewManage(manageBuf)
+	t := data.NewTopic()
+	h := data.NewHandle()
+	admin := data.NewAdmin(m, t, h, logger)
+	for s, checkFunc := range checkMap {
+		admin.AddCheckFunc(s, checkFunc)
+	}
+	registeredMsgHandler := DefaultRegisteredMsgHandler(admin, logger)
+
+	for key, handler := range registeredMsgHandler {
+		admin.RegisteredMsgHandler(key, handler)
+	}
+	return &wsPlugin{logger: logger, manageBuf: manageBuf,
+		registeredMsgHandler: registeredMsgHandler, checkMap: checkMap, admin: admin, adminCase: biz.NewAdmin(admin)}
+}