This package allows you to easily create web application servers with websocket support. Communication is processed using a text based structure consisting of a command and optionally data.
To create a new websocket handler call NewHandler().
Now you have to use Handler.UpgradeHandler to upgrade a normal HTTP request to websocket.
handler := websocket.NewHandler()
http.HandleFunc("/ws", handler.UpgradeHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
You can handle client requests by registering handle functions for specific command strings using Handler.Handle
A handler for open
can be registered and will be called every time a connection is opened. The message will be the clients session ID.
handler.Handle("open", func(msg []byte, authToken string) *Message {
// Parse message here
sessionid = uuid.Parse(msg)
// Validate auth token if necessary
return NewMessage("welcome", []byte("Hello " string(msg)))
// This will write "Hello xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" to the client using the command "welcome"
})
The server can push commands and data to the clients using channels for which the clients have to register as listeners.
Channels can have validation functions attached on setup to restrict which clients will be allowed to register as listeners.
These validation functions will be called whenever a client tries to register as a listener with the auth token that client submitted when connecting.
A return value of nil
will be considered a successful validation while any error will be considered a validation failure and therefore prevent the client from registering as a listener. The errors will not be relayed to the client to improve security. Instead a generic error message will be sent.
The server may also push commands and data to specific clients whenever necessary using their session ID.
handler.RegisterListenChannel("test", nil) // Anyone can register as a listener
handler.RegisterListenChannel("restricted", func(t string) error {
if t != "valid" {
return errors.New("Invalid token")
}
return nil
})
handler.WriteToChannel("test", NewMessage("thanks", []byte("Thank you for listening!")))
handler.WriteToClient(sessionid, NewMessage("direct", []byte("This message is only sent to a single client")))