websocket支持过滤消息类型

This commit is contained in:
kercylan98 2023-05-09 18:04:05 +08:00
parent b00625207b
commit b5c25a3dc8
3 changed files with 53 additions and 14 deletions

View File

@ -9,4 +9,7 @@ var (
ErrMessageTypeErrorAttrs = errors.New("MessageTypePacket must contain error and MessageErrorAction")
ErrNetworkOnlySupportHttp = errors.New("the current network mode is not compatible with HttpRouter, only NetworkHttp is supported")
ErrNetworkIncompatibleHttp = errors.New("the current network mode is not compatible with NetworkHttp")
ErrWebsocketMessageTypeException = errors.New("unknown message type, will not work")
ErrNotWebsocketUseMessageType = errors.New("message type filtering only supports websocket and does not take effect")
ErrWebsocketIllegalMessageType = errors.New("illegal message type")
)

View File

@ -5,6 +5,19 @@ import (
"go.uber.org/zap"
)
const (
// WebsocketMessageTypeText 表示文本数据消息。文本消息负载被解释为 UTF-8 编码的文本数据
WebsocketMessageTypeText = 1
// WebsocketMessageTypeBinary 表示二进制数据消息
WebsocketMessageTypeBinary = 2
// WebsocketMessageTypeClose 表示关闭控制消息。可选消息负载包含数字代码和文本。使用 FormatCloseMessage 函数来格式化关闭消息负载
WebsocketMessageTypeClose = 8
// WebsocketMessageTypePing 表示 ping 控制消息。可选的消息负载是 UTF-8 编码的文本
WebsocketMessageTypePing = 9
// WebsocketMessageTypePong 表示一个 pong 控制消息。可选的消息负载是 UTF-8 编码的文本
WebsocketMessageTypePong = 10
)
type Option func(srv *Server)
// WithProd 通过生产模式运行服务器
@ -14,6 +27,26 @@ func WithProd() Option {
}
}
// WithWebsocketMessageType 设置仅支持特定类型的Websocket消息
func WithWebsocketMessageType(messageTypes ...int) Option {
return func(srv *Server) {
if srv.network != NetworkWebsocket {
log.Warn("WitchWebsocketMessageType", zap.String("Network", string(srv.network)), zap.Error(ErrNotWebsocketUseMessageType))
return
}
var supports = make(map[int]bool)
for _, messageType := range messageTypes {
switch messageType {
case WebsocketMessageTypeText, WebsocketMessageTypeBinary, WebsocketMessageTypeClose, WebsocketMessageTypePing, WebsocketMessageTypePong:
supports[messageType] = true
default:
log.Warn("WitchWebsocketMessageType", zap.Int("MessageType", messageType), zap.Error(ErrWebsocketMessageTypeException))
}
}
srv.supportMessageTypes = supports
}
}
// WithMessageBufferSize 通过特定的消息缓冲池大小运行服务器
// - 默认大小为 1024
// - 消息数量超出这个值的时候,消息处理将会造成更大的开销(频繁创建新的结构体),同时服务器将输出警告内容

View File

@ -53,6 +53,7 @@ type Server struct {
ginServer *gin.Engine // HTTP模式下的路由器
httpServer *http.Server // HTTP模式下的服务器
grpcServer *grpc.Server // GRPC模式下的服务器
supportMessageTypes map[int]bool // websocket模式下支持的消息类型
gServer *gNet // TCP或UDP模式下的服务器
messagePool *synchronization.Pool[*message] // 消息池
@ -228,12 +229,14 @@ func (slf *Server) Run(addr string) error {
if err := ws.SetReadDeadline(time.Now().Add(time.Second * 30)); err != nil {
panic(err)
}
_, packet, err := ws.ReadMessage()
messageType, packet, err := ws.ReadMessage()
if err != nil {
panic(err)
}
if !slf.supportMessageTypes[messageType] {
panic(ErrWebsocketIllegalMessageType)
}
slf.PushMessage(MessageTypePacket, conn, packet)
}
})
go func() {