Files
wiscast/message.go
AlexandreRouma f352b50f18 progress
2025-11-05 02:02:36 -05:00

112 lines
2.8 KiB
Go

package main
// Packages
import "encoding/json"
import "errors"
import "time"
import "github.com/gorilla/websocket"
//import "log"
// Backend message object
type Message struct {
// Type of message
mtype string;
// Arguments of the message
arguments map[string]interface{};
}
// Get the display back to its idle state
func encodeMessage(msg Message) []byte {
// Create the message map and set the message type
msgJson := map[string]interface{}{};
msgJson["type"] = msg.mtype;
// Add all arguments
for k, v := range msg.arguments {
// Skip the type key
if (k == "type") { continue };
// Add the key/value to the argument map
msgJson[k] = v;
}
// Serialize the message
data, _ := json.Marshal(msgJson);
// Return the data
return data;
}
// Get the display back to its idle state
func decodeMessage(data []byte) (Message, error) {
// Attempt to parse the message
var msgJson map[string]interface{};
err := json.Unmarshal(data, &msgJson);
if (err != nil) { return Message{}, err; }
// If no message type is given, return an error
if msgJson["type"] == nil { return Message{}, errors.New("Invalid message"); }
// If the message type is not a string, return an error
mtype, valid := msgJson["type"].(string);
if !valid { return Message{}, errors.New("Invalid message"); }
// Create the message object
msg := Message{ mtype: mtype, arguments: map[string]interface{}{} };
// Extract the arguments
for k, v := range msgJson {
// Skip the type key
if (k == "type") { continue; }
// Add the key/value to the argument map
msg.arguments[k] = v;
}
// Return the decoded message with no error
return msg, nil;
}
// Encode a message and send it over a WebSocket
func sendMessage(sock *websocket.Conn, msg Message) {
// Encode and send the message
sock.WriteMessage(websocket.TextMessage, encodeMessage(msg));
}
// Receive a message from a WebSocket and decode it
func recvMessage(sock *websocket.Conn, timeoutMS int) (Message, error) {
for {
// Configure the timeout
if timeoutMS > 0 {
// Milliseconds given
sock.SetReadDeadline(time.Now().Add(time.Millisecond * time.Duration(timeoutMS)))
} else {
// No timeout given
sock.SetReadDeadline(time.Time{});
}
// Receive a WebSocket message
mt, msgData, err := sock.ReadMessage();
// If there was an error, give up and return it
if (err != nil) { return Message{}, err; }
// If the message is not a text message, continue waiting
if (mt != websocket.TextMessage) { continue; }
// Return the decoded message
return decodeMessage(msgData);
}
}
// Encode an error message and send it over a WebSocket
func sendErrorMessage(sock *websocket.Conn, code int) {
// Send the error message
sock.WriteMessage(websocket.TextMessage, encodeMessage(Message{
mtype: "error",
arguments: map[string]interface{}{
"code": code,
},
}));
}