golem

package module
v0.0.0-...-82b774e Latest Latest
Warning

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

Go to latest
Published: Nov 14, 2013 License: Apache-2.0 Imports: 8 Imported by: 0

README

golem v0.4.4

A lightweight extendable Go WebSocket-framework with client library.

License

Golem is available under the Apache License, Version 2.0

Installation

go get github.com/trevex/golem

Client

A client is also available and heavily used in the examples. More information on how the client is used can be found in the client repository.

Simple Example

Server:

type Hello struct {
	From string `json:"from"`
}
type Answer struct {
	Msg string `json:"msg"`
}
func hello(conn *golem.Connection, data *Hello) {
	conn.Emit("answer", &Answer{"Thanks, "+ data.From + "!"})
}
func main() {
	myrouter := golem.NewRouter()
	myrouter.On("hello", hello)
	http.HandleFunc("/ws", myrouter.Handler())
	http.ListenAndServe(":8080", nil)
}

Client:

var conn = new golem.Connection("ws://127.0.0.1:8080/ws", true);
conn.on("answer", function(data) {
    console.log("Answer: "+data.msg);
});
conn.on("open", function() {
    conn.emit("hello", { from: "Client" });
});

Output in client console would be Thanks, Client!.

Documentation

The documentation is provided via godoc.

Wiki & Tutorials

More informations and insights can be found on the wiki page along with a tutorial series to learn how to use golem:

More Examples

Several examples are available in the example repository. To use them simply checkout the repository and make sure you installed (go get) golem before. A more detailed guide on how to use them is located in their repository.

History

  • v0.1.0
    • Basic API layout and documentation
  • v0.2.0
    • Evented communication system and routing
    • Basic room implementation (lobbies renamed to rooms for clarity)
  • v0.3.0
    • Protocol extensions through Parsers
    • Room manager for collections of rooms
  • v0.4.0
    • Protocol interchangable
    • Several bugfixes
    • Client up-to-date
  • v0.4.2
    • Connection type can be extended
    • Close added to connection
  • v0.4.3
    • RoomManager emiting create- and remove-events (remove if room has insufficient users)
  • v0.4.4
    • RoomManager manages set of connection dependent options, see example_chat_options.go
    • Router provides OnConnect callback

Special thanks

  • Gary Burd (for the great WebSocket protocol implementation and insights through his examples)
  • Andrew Gallant (for help on golang-nuts mailing list)
  • Kortschak (for help on golang-nuts mailing list)

Contributors

TODO

  • Verbose and configurable logging
  • Testing

Documentation

Overview

Golem is a lightweight WebSocket-framework. it simplifies interaction with websockets by exposing an event-based system allowing easy prototyping of WebSocket-interaction. To achieve this a simple extendable JSON-based protocol is used by default, but custom protocol or simple protocol extensions are supported.

For more general information, visit the wiki: https://github.com/trevex/golem/wiki

Examples can be found in the example repository: https://github.com/trevex/golem_examples

The client documentation and repository: https://github.com/trevex/golem_client

Index

Constants

View Source
const (

	// BinaryMode represents binary WebSocket operations
	BinaryMode = 1
	// TextMode represents text-based WebSocket operations
	TextMode = 2
)
View Source
const (
	CloseConnectionOnLastRoomLeft = 1
)

Variables

This section is empty.

Functions

func SetDefaultConnectionExtension

func SetDefaultConnectionExtension(constructor interface{})

SetDefaultConnectionExtension sets the initial extension used by all freshly instanced routers. For more information see the Router SetConnectionExtension() - method.

func SetDefaultProtocol

func SetDefaultProtocol(protocol Protocol)

SetDefaultProtocol sets the protocol that should be used by newly created routers. Therefore every router created after changing the default protocol will use the new protocol by default.

Types

type Connection

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

Connection holds information about the underlying WebSocket-Connection, the associated router and the outgoing data channel.

func (*Connection) Close

func (conn *Connection) Close()

Close closes and cleans up the connection.

func (*Connection) Emit

func (conn *Connection) Emit(event string, data interface{})

Emit event with provided data. The data will be automatically marshalled and packed according to the active protocol of the router the connection belongs to.

type DefaultJSONProtocol

type DefaultJSONProtocol struct{}

DefaultJSONProtocol is the initial protocol used by golem. It implements the Protocol-Interface. (Note: there is an article about this simple protocol in golem's wiki)

func (*DefaultJSONProtocol) GetReadMode

func (_ *DefaultJSONProtocol) GetReadMode() int

Return TextMode because JSON is transmitted using the text mode of WebSockets.

func (*DefaultJSONProtocol) GetWriteMode

func (_ *DefaultJSONProtocol) GetWriteMode() int

Return TextMode because JSON is transmitted using the text mode of WebSockets.

func (*DefaultJSONProtocol) MarshalAndPack

func (_ *DefaultJSONProtocol) MarshalAndPack(name string, structPtr interface{}) ([]byte, error)

Marshals structure into JSON and packs event name in as well. If not successful second return value is an error.

func (*DefaultJSONProtocol) Unmarshal

func (_ *DefaultJSONProtocol) Unmarshal(data interface{}, typePtr interface{}) error

Unmarshals data into requested structure. If not successful the function return an error.

func (*DefaultJSONProtocol) Unpack

func (_ *DefaultJSONProtocol) Unpack(data []byte) (string, interface{}, error)

Unpack splits the event name from the incoming message.

type Hub

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

The Hub manages all active connection, but should only be used directly if broadcasting of data or an event to all connections is desired. The Hub should not be instanced directly. Use GetHub to get the active hub for broadcasting messages.

func GetHub

func GetHub() *Hub

GetHub retrieves and returns pointer to golem's active hub.

func (*Hub) Broadcast

func (hub *Hub) Broadcast(event string, data interface{})

Broadcast emits an event with data to ALL active connections.

type Protocol

type Protocol interface {
	// Unpack splits/extracts event name from incoming data.
	// Takes incoming data bytes as parameter and returns the event name, interstage data and if an error occured the error.
	Unpack([]byte) (string, interface{}, error)
	// Unmarshals leftover data into associated type of callback.
	// Takes interstage product and desired type as parameters and returns error if unsuccessful.
	Unmarshal(interface{}, interface{}) error
	// Marshal and pack data into byte array
	// Takes event name and type pointer as parameters and returns byte array or error if unsuccessful.
	MarshalAndPack(string, interface{}) ([]byte, error)
	// Returns read mode, that should be used for this protocol.
	GetReadMode() int
	// Returns write mode, that should be used for this protocol
	GetWriteMode() int
}

Protocol-interface provides the required methods necessary for any protocol, that should be used with golem, to implement. The evented system of golem needs several steps to process incoming data:

  1. Unpack to extract the name of the event that was emitted. (next golem checks if an event handler exists, if does, the next method is called with the associated structure of the event)
  2. Unmarshal the interstage product from unpack into the desired type.

For emitting data the process is reversed, but merged in a single function, because evaluation the desired unmarshaled type is not necessary:

  1. MarshalAndPack marhals the data and the event name into an array of bytes.

The GetReadMode and GetWriteMode functions define what kind of WebSocket- Communication will be used.

type Room

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

Rooms are groups of connections. A room provides methods to communicate with all members of the group simultaneously.

func NewRoom

func NewRoom() *Room

Creates and initialised a room and returns pointer to it.

func (*Room) Emit

func (r *Room) Emit(event string, data interface{})

Emits message event to all members of the room.

func (*Room) Join

func (r *Room) Join(conn *Connection)

Join adds the provided connection to the room.

func (*Room) Leave

func (r *Room) Leave(conn *Connection)

Leave removes the connection from the room, if it previously was member of the room.

func (*Room) Stop

func (r *Room) Stop()

Stops and shutsdown the room. After calling Stop the room can be safely deleted.

type RoomManager

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

Handles any count of lobbies by keys. Currently only strings are supported as keys (room names). As soon as generics are supported any key should be able to be used. The methods are used similar to single rooms but preceded by the key.

func NewRoomManager

func NewRoomManager() *RoomManager

NewRoomManager initialises a new instance and returns the a pointer to it.

func (*RoomManager) Destroy

func (rm *RoomManager) Destroy(name string)

Remove connections from a particular room and delete the room

func (*RoomManager) Emit

func (rm *RoomManager) Emit(to string, event string, data interface{})

Emit a message, that can be fetched using the golem client library. The provided data interface will be automatically marshalled according to the active protocol.

func (*RoomManager) Join

func (rm *RoomManager) Join(name string, conn *Connection)

Join adds the connection to the specified room.

func (*RoomManager) Leave

func (rm *RoomManager) Leave(name string, conn *Connection)

Leave removes the connection from the specified room.

func (*RoomManager) LeaveAll

func (rm *RoomManager) LeaveAll(conn *Connection)

LeaveAll removes the connection from all joined rooms of this manager. This is an important step and should be called OnClose for all connections, that could have joined a room of the manager, to keep the member reference count of the manager accurate.

func (*RoomManager) On

func (rm *RoomManager) On(eventName string, callback interface{})

The room manager can emit several events. At the moment there are two events: "create" - triggered if a room was created and "remove" - triggered when a room was removed because of insufficient users For both the callback needs to be of the type func(string) where the argument

func (*RoomManager) SetConnectionOptions

func (rm *RoomManager) SetConnectionOptions(conn *Connection, options uint32, overwrite bool)

func (*RoomManager) Stop

func (rm *RoomManager) Stop()

Stop the message loop and shutsdown the manager. It is safe to delete the instance afterwards.

type Router

type Router struct {

	// If set, the values the Origin header will be checked against and access is only allowed
	// on a match; otherwise no Origin checking is performed. *This overrides the
	// Access-Control-Allow-Origin header!*
	Origins []string
	// contains filtered or unexported fields
}

Router handles multiplexing of incoming messenges by typenames/events. Initially a router uses heartbeats and the default protocol.

func NewRouter

func NewRouter() *Router

NewRouter intialises a new instance and returns the pointer.

func (*Router) AddProtocolExtension

func (router *Router) AddProtocolExtension(extensionFunc interface{}) error

The AddProtocolExtension-function allows adding of custom parsers for custom types. For any Type T the parser function would look like this:

func (interface{}) (T, bool)

The interface's type is depending on the interstage product of the active protocol, by default for the JSON-based protocol it is []byte and therefore the function could be simplified to:

func ([]byte) (T, bool)

Or in general if P is the interstage product:

func (*P) (T, bool)

The boolean return value is necessary to verify if parsing was successful. All On-handling function accepting T as input data will now automatically use the custom extension. For an example see the example_data.go file in the example repository.

func (*Router) Handler

func (router *Router) Handler() func(http.ResponseWriter, *http.Request)

Handler creates a handler function for this router, that can be used with the http-package to handle WebSocket-Connections.

func (*Router) On

func (router *Router) On(name string, callback interface{})

The On-function adds callbacks by name of the event, that should be handled. For type T the callback would be of type:

func (*golem.Connection, *T)

Type T can be any type. By default golem tries to unmarshal json into the specified type. If a custom protocol is used, it will be used instead to process the data. If type T is registered to use a protocol extension, it will be used instead. If type T is interface{} the interstage data of the active protocol will be directly forwarded! (Note: the golem wiki has a whole page about this function)

func (*Router) OnClose

func (router *Router) OnClose(callback interface{}) error

OnClose sets the callback, that is called when the connection is closed. It accept function of the type func(*Connection) by default or functions taking extended connection types if previously registered.

func (*Router) OnConnect

func (router *Router) OnConnect(callback interface{}) error

OnConnection sets the callback, that is called when a websocket connection was successfully established, it is therefore called after the handshake. It accept function of the type func(*Connection, *http.Request) by default or functions taking extended connection types if previously registered. The http.Request object can be used for connection metadata information.

func (*Router) OnHandshake

func (router *Router) OnHandshake(callback func(http.ResponseWriter, *http.Request) bool)

OnHandshake sets the callback for handshake verfication. If the handshake function returns false the request will not be upgraded. The http.Request object will be passed into OnConnect as well.

func (*Router) SetConnectionExtension

func (router *Router) SetConnectionExtension(constructor interface{})

SetConnectionExtension sets the extension for this router. A connection extension is an extended connection structure, that afterwards can be used by On-handlers as well (use-cases: add persistent storage to connection, additional methods et cetera). The SetConnectionExtension function takes the constructor of the custom format to be able to use and create it on connection to the router. For type E the constructor needs to fulfil the following requirements:

func NewE(conn *Connection) *E

Afterwards On-handler can us this extended type:

router.On(func (extendedConn E, data Datatype) { ... })

For an example have a look at the example repository and have a look at the 'example_connection_extension.go'.

func (*Router) SetHeartbeat

func (router *Router) SetHeartbeat(flag bool)

SetHeartbeat activates or deactivates the heartbeat depending on the flag parameter. By default heartbeats are activated.

func (*Router) SetProtocol

func (router *Router) SetProtocol(protocol Protocol)

SetProtocol sets the protocol of the router to the supplied implementation of the Protocol interface.

Jump to

Keyboard shortcuts

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