websocket

package module
v0.0.0-...-8f2e25d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2018 License: BSL-1.0 Imports: 7 Imported by: 0

README

GoEasyWebsocket

CircleCI Coveralls Codacy GoDoc

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.

Setup

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))

Client requests

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"
})

Server push

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")))

Documentation

Overview

Package websocket provides an easy, text-based way to build a websocket server.

It uses a command based message structure. The command can have a length between 1 and 255 characters and may contain all characters besides a colon although it is recommended to use short, lowercase, one word commands to keep the messages as short as possible.

The command is followed by a colon and a space after which the optional content is appended.

This format keeps all messages as human-readable as possible to allow for easy diagnosis of errors.

You can register a handler for a specific command which allows you to respond directly. This is the recommended way of responding to a command although it is also possible to store the users session id and use it to respond later. This might be useful when complex computations are necessary to generate the response and you don't want to block the read loop.

It is possible to address multiple clients at once through the use of channels. You have to register a channel name which clients can then use to register as listeners. A message submitted to a channel will be sent to all listening clients.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type HandleFunc

type HandleFunc func([]byte, string) *Message

HandleFunc is a type used to store handle functions for ws commands. Handle functions take the message as a byte slice and the auth token as a string and may return a message that will be submitted to the client or nil if no response is necessary.

type Handler

type Handler struct {
	ValidateFunction func(string) error // ValidateFunction is a function that validates the auth token and returns an error if it is invalid
	// contains filtered or unexported fields
}

Handler is the base type of a websocket endpoint.

It stores all relevant connections and is used to manage command handlers and channels.

The only public field is ValidateFunction which stores a function that is used to validate the users auth token.

Disabling authentication is currently not supported but you can simply supply a validation function that returns nil in all cases.

func(_ string) error {
	return nil
}

Please make sure to set the auth cookie anyway as it is required for the connection to be accepted.

func NewHandler

func NewHandler() *Handler

NewHandler creates a new Handler and returns a pointer to it.

func (*Handler) Handle

func (h *Handler) Handle(cmd string, action HandleFunc) error

Handle registers a handle function for a command

func (*Handler) RegisterListenChannel

func (h *Handler) RegisterListenChannel(name string, validationFunc func(string) error) error

RegisterListenChannel registers a channel for writing to clients listening on it. It takes the channel name as a string and a validation function taking a string and returning an error as arguments. You may use nil instead of a validation function in case no validation is required. When using a validation function, a return value of nil is considered as validation successful while an error means validation failed.

func (*Handler) UpgradeHandler

func (h *Handler) UpgradeHandler(w http.ResponseWriter, r *http.Request)

UpgradeHandler upgrades http requests to websocket and starts the necessary goroutines for handling receiving and sending messages

func (*Handler) WriteToChannel

func (h *Handler) WriteToChannel(channel string, msg *Message) error

WriteToChannel sends a message to all clients listening to a specific channel. It takes the channel name and a pointer to a message as arguments. It will fail if the command is nil or longer than 255 characters or if the channel does not exist.

func (*Handler) WriteToClient

func (h *Handler) WriteToClient(user uuid.UUID, msg *Message) error

WriteToClient sends a message to a specific client. It takes the users session id as an UUID and a pointer to a message as arguments. It will fail if the command is nil or longer than 255 characters or if the session does not exist.

type Message

type Message struct {
	// contains filtered or unexported fields
}

Message is the type used to handle websocket messages. It is meant to be initialized using

NewMessage(command string, data []byte)

to ensure only valid messages are created in the first place. For that reason the fields are not exported.

func NewMessage

func NewMessage(cmd string, data []byte) (*Message, error)

NewMessage creates a new message from a command string and content submitted as a byte slice. In case no content should be sent, please use nil instead of an empty slice.

There are some rules enforced by NewMessage():

- Commands may not be empty or longer than 255 characters

- Commands may not contain a colon

- Commands may not be "websocket" as this command is reserved

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL