Documentation
¶
Overview ¶
Package gpoll manages long-polling. Long-polling is a means of near-realtime data transfer that utilizes keep-alive requests to allow clients to receive data as it becomes available. Notable uses for long-polling include push notification and chat clients.
This package has the aim of making message distribution as quick as possible. The way this is accomplished in gpoll is by utilizing coroutines (goroutines) and tracking them so that coroutines are automatically created and terminated as necessary based on the number of clients connected and your configuration.
Getting Started ¶
To use gpoll, you first need to setup a Broadcaster object. The Broadcaster object has several fields you can tweak to tune the behavior of the Broadcaster. For instance, the ClientBufferSize dictates how many massages you will allow each client buffer to store. However, because client removal is automated, the package will sense when a buffer is full, then remove that client since the program assumes this means the client is no longer listening.
If you wish to just drop in the package and use it right away, you can just have the server use the DefaultBroadcaster. This is already available and by calling the ListenAndBroadcast() function in the global context, your server will default to this object and you're ready to go. An example of such a setup is:
package main
import (
"github.com/corvuscrypto/gpoll"
"net/http"
)
func HandleMessage(w http.ResponseWriter, r *http.Request) {
// code to detect message and do other stuff as
// you please with the request.
var msg string = "blah blah blah"
gpoll.Send(msg) //send the message string
w.WriteHeader(200)
}
func main(){
gpoll.ListenAndBroadcast("/path/to/listen/on")
http.HandleFunc("/send", HandleMessage)
http.ListenAndServe(":8080",nil)
}
It's as easy as that.
Tricks ¶
Total reset. Okay this is probably something that should never be done unless absolutely necessary, but if you need to do a full reset and kick all your users, just call the CleanUp() function. Since the CleanUp function takes an argument in the form of an int slice made up of the INDICES (not IDs) of the goroutines present within a Broadcaster, just pass in a slice containing all indices of the Broadcaster.Routines slice. This would look like this:
var resetSlice []int
for i,_ := range Broadcaster.Routines {
resetSlice = append(resetSlice, i)
}
Broadcaster.CleanUp(resetSlice)
I'll add in support for individual client removal, but you can even implement your own client removal since the number before the '$' in a client ID is the goroutine ID. Just search the Routine object that contains that ID for your client within the Clients slice and remove it.
Index ¶
- Variables
- func ListenAndBroadcast(path string, srv ...*http.ServeMux)
- func Send(msg string)
- func UUID() string
- type Broadcaster
- func (b *Broadcaster) AddClient() (string, int)
- func (b *Broadcaster) Benchmark(msgSize int, clients int, numMsgs int) error
- func (b *Broadcaster) CleanUp(toClean []int)
- func (b *Broadcaster) GetChannel(cid string, rid int) (chan string, error)
- func (b *Broadcaster) HandleMessage(ch <-chan string, in int)
- func (b *Broadcaster) HandleRequests(w http.ResponseWriter, r *http.Request)
- func (b *Broadcaster) ListenAndBroadcast(path string, srv ...*http.ServeMux)
- func (b *Broadcaster) Send(msg string)
- type Client
- type Routine
- type TestStruct
Constants ¶
This section is empty.
Variables ¶
var DefaultBroadcaster = NewBroadcaster()
Functions ¶
func ListenAndBroadcast ¶
ListenAndBroadcast uses the DefaultBroadcaster to set up a handler for polling requests. If supplied with a ServeMux object, it will add the handler to it, otherwise it defaults to using the DefaultServeMux object.
func Send ¶
func Send(msg string)
Send uses the DefaultBroadcaster object to send a message to all registered clients.
func UUID ¶
func UUID() string
UUID generator. I can't take credit for this as it was obtained from a golang-nuts discussion board (https://groups.google.com/forum/#!msg/golang-nuts/d0nF_k4dSx4/rPGgfXv6QCoJ). Acknowledgements to Russ Cox for the code and for saving me time from reading through the official UUID documentation.
Types ¶
type Broadcaster ¶
type Broadcaster struct {
// Number of clients per routine
RoutineMaxClients int
// Maximum number of messages per client channel
ClientBufferSize int
// Maximum number of messages to hold in each routine's buffer
RoutineBufferSize int
// Number of milliseconds to wait before broadcasting message in master buffer
// default is 0, but can be set to compensate for the time it takes for
// clients to reconnect to the polling service.
SyncDelayMs int
// Routines holds routine references within the Broadcaster to allow proper
// message handling and client maintenance.
Routines []Routine
// WG is a WaitGroup for ensuring synchronicity when necessary
WG sync.WaitGroup
// Mux is a mutex for maintaining proper data control and preventing race
// conditions during asynchronous broadcasting and client management.
Mux sync.Mutex
// IsBenchmarking is used for controlling benchmark behavior
IsBenchmarking bool
// BenchData is an array for holding data during benchmarking. This will
// always be cleared after benchmarking to save memory.
BenchData []TestStruct
// Command salt. This will automatically be generated. You can generate one
// if you like, but make sure it is not publicly known.
CSalt string
}
The Broadcaster struct contains configuration information to dictate long-polling behavior. The only parameters you have to assign values to are RoutineMaxClients, ClientBufferSize, and RoutineBufferSize
func NewBroadcaster ¶
func NewBroadcaster() *Broadcaster
NewBroadcaster returns a pointer to a Broadcaster with the default settings of RoutineMaxClients: 1000, ClientBufferSize: 100, RoutineBufferSize: 200, and SyncDelayMs: 0.
func (*Broadcaster) AddClient ¶
func (b *Broadcaster) AddClient() (string, int)
AddClient adds a client to the associated Broadcaster and returns the client ID and the routine id that manages the client.
func (*Broadcaster) Benchmark ¶
func (b *Broadcaster) Benchmark(msgSize int, clients int, numMsgs int) error
Benchmark registers virtual clients and tests the server by sending messages of size 'msgSize' to all of them. The data is collected automatically and some basic statistics are output. This only looks at time, but may look at memory usage in the future.
func (*Broadcaster) CleanUp ¶
func (b *Broadcaster) CleanUp(toClean []int)
CleanUp is used to terminate routines by the IDs specified in the supplied toClean parameter. This can also be used directly to shut a routine down if necessary, or trigger a full purge.
func (*Broadcaster) GetChannel ¶
func (b *Broadcaster) GetChannel(cid string, rid int) (chan string, error)
GetChannel retrieves the reference to the receiving channel for a client based on the supplied client id ('cid') and the routine id ('rid').
func (*Broadcaster) HandleMessage ¶
func (b *Broadcaster) HandleMessage(ch <-chan string, in int)
HandleMessage is the basis of all coroutines within the gpoll package. It contains the code that automatically manages client removal and broadcasting. Look at the source to figure out more about this function.
func (*Broadcaster) HandleRequests ¶
func (b *Broadcaster) HandleRequests(w http.ResponseWriter, r *http.Request)
HandleRequests takes a typical http request and returns a new client ID if the client wasn't previously registered, or a broadcasted message if the client is registered.
func (*Broadcaster) ListenAndBroadcast ¶
func (b *Broadcaster) ListenAndBroadcast(path string, srv ...*http.ServeMux)
ListenAndBroadcast uses the associated Broadcaster object to set up a handler for polling requests. If supplied with a ServeMux object, it will add the handler to it, otherwise it defaults to using the DefaultServeMux object.
func (*Broadcaster) Send ¶
func (b *Broadcaster) Send(msg string)
Send uses the associated Broadcster object to send a message to all registered clients
type Client ¶
type Client struct {
//ID is the UUID of the client.
ID string
//Pipe is the receiving channel of the client.
Pipe chan string
}
The Client struct holds the client id, and the channel reference for that client.
type Routine ¶
type Routine struct {
sync.Mutex
// Id of the routine. This is generated automatically.
ID int
// Pipe holds the reference for the receiving channel of the routine.
Pipe chan string
// Clients holds a collection of Client objects for tracking and management.
Clients []Client
}
The Routine struct holds information about routines, as well as the the references to clients.
type TestStruct ¶
type TestStruct struct {
// Ns is the time taken to complete a single broadcast in nanoseconds.
Ns int64
// Clients represents the number of total clients being broadcasted to.
Clients int
// Routines represents the total number of routines being managed by the server.
Routines int
}
TestStruct holds benchmarking information for tuning your server.