mirror of
https://github.com/kataras/iris.git
synced 2025-12-19 19:07:06 +00:00
Version 3.0.0-beta cleaned
This commit is contained in:
145
websocket/serializer.go
Normal file
145
websocket/serializer.go
Normal file
@@ -0,0 +1,145 @@
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/kataras/iris/utils"
|
||||
)
|
||||
|
||||
/*
|
||||
serializer, [de]serialize the messages from the client to the server and from the server to the client
|
||||
*/
|
||||
|
||||
// The same values are exists on client side also
|
||||
const (
|
||||
stringMessageType messageType = iota
|
||||
intMessageType
|
||||
boolMessageType
|
||||
bytesMessageType
|
||||
jsonMessageType
|
||||
)
|
||||
|
||||
const (
|
||||
prefix = "iris-websocket-message:"
|
||||
separator = ";"
|
||||
prefixLen = len(prefix)
|
||||
separatorLen = len(separator)
|
||||
prefixAndSepIdx = prefixLen + separatorLen - 1
|
||||
prefixIdx = prefixLen - 1
|
||||
separatorIdx = separatorLen - 1
|
||||
)
|
||||
|
||||
var (
|
||||
separatorByte = separator[0]
|
||||
buf = utils.NewBufferPool(256)
|
||||
prefixBytes = []byte(prefix)
|
||||
)
|
||||
|
||||
type (
|
||||
messageType uint8
|
||||
)
|
||||
|
||||
func (m messageType) String() string {
|
||||
return strconv.Itoa(int(m))
|
||||
}
|
||||
|
||||
func (m messageType) Name() string {
|
||||
if m == stringMessageType {
|
||||
return "string"
|
||||
} else if m == intMessageType {
|
||||
return "int"
|
||||
} else if m == boolMessageType {
|
||||
return "bool"
|
||||
} else if m == bytesMessageType {
|
||||
return "[]byte"
|
||||
} else if m == jsonMessageType {
|
||||
return "json"
|
||||
}
|
||||
|
||||
return "Invalid(" + m.String() + ")"
|
||||
|
||||
}
|
||||
|
||||
// serialize serializes a custom websocket message from server to be delivered to the client
|
||||
// returns the string form of the message
|
||||
// Supported data types are: string, int, bool, bytes and JSON.
|
||||
func serialize(event string, data interface{}) (string, error) {
|
||||
var msgType messageType
|
||||
var dataMessage string
|
||||
|
||||
if s, ok := data.(string); ok {
|
||||
msgType = stringMessageType
|
||||
dataMessage = s
|
||||
} else if i, ok := data.(int); ok {
|
||||
msgType = intMessageType
|
||||
dataMessage = strconv.Itoa(i)
|
||||
} else if b, ok := data.(bool); ok {
|
||||
msgType = boolMessageType
|
||||
dataMessage = strconv.FormatBool(b)
|
||||
} else if by, ok := data.([]byte); ok {
|
||||
msgType = bytesMessageType
|
||||
dataMessage = string(by)
|
||||
} else {
|
||||
//we suppose is json
|
||||
res, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
msgType = jsonMessageType
|
||||
dataMessage = string(res)
|
||||
}
|
||||
|
||||
b := buf.Get()
|
||||
b.WriteString(prefix)
|
||||
b.WriteString(event)
|
||||
b.WriteString(separator)
|
||||
b.WriteString(msgType.String())
|
||||
b.WriteString(separator)
|
||||
b.WriteString(dataMessage)
|
||||
dataMessage = b.String()
|
||||
buf.Put(b)
|
||||
|
||||
return dataMessage, nil
|
||||
|
||||
}
|
||||
|
||||
// deserialize deserializes a custom websocket message from the client
|
||||
// ex: iris-websocket-message;chat;4;themarshaledstringfromajsonstruct will return 'hello' as string
|
||||
// Supported data types are: string, int, bool, bytes and JSON.
|
||||
func deserialize(event string, websocketMessage string) (message interface{}, err error) {
|
||||
t, formaterr := strconv.Atoi(websocketMessage[prefixAndSepIdx+len(event)+1 : prefixAndSepIdx+len(event)+2]) // in order to iris-websocket-message;user;-> 4
|
||||
if formaterr != nil {
|
||||
return nil, formaterr
|
||||
}
|
||||
_type := messageType(t)
|
||||
_message := websocketMessage[prefixAndSepIdx+len(event)+3:] // in order to iris-websocket-message;user;4; -> themarshaledstringfromajsonstruct
|
||||
|
||||
if _type == stringMessageType {
|
||||
message = string(_message)
|
||||
} else if _type == intMessageType {
|
||||
message, err = strconv.Atoi(_message)
|
||||
} else if _type == boolMessageType {
|
||||
message, err = strconv.ParseBool(_message)
|
||||
} else if _type == bytesMessageType {
|
||||
message = []byte(_message)
|
||||
} else if _type == jsonMessageType {
|
||||
err = json.Unmarshal([]byte(_message), message)
|
||||
} else {
|
||||
return nil, fmt.Errorf("Type %s is invalid for message: %s", _type.Name(), websocketMessage)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// getCustomEvent return empty string when the websocketMessage is native message
|
||||
func getCustomEvent(websocketMessage string) string {
|
||||
if len(websocketMessage) < prefixAndSepIdx {
|
||||
return ""
|
||||
}
|
||||
s := websocketMessage[prefixAndSepIdx:]
|
||||
evt := s[:strings.IndexByte(s, separatorByte)]
|
||||
return evt
|
||||
}
|
||||
Reference in New Issue
Block a user