sphere

package module
v0.0.0-...-fff2126 Latest Latest
Warning

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

Go to latest
Published: Mar 14, 2016 License: MIT Imports: 15 Imported by: 0

README

go-sphere

Build Status Coverage Status GoDoc

Go-Sphere is an open source realtime framework to scale websocket horizontally (across multiple hosts) via pub/sub synchronization. Sphere supports both real-time bidirectional event-based communication and group communication.

Usage

To create websocket server with gin webserver

package main

import (
  "github.com/samuelngs/go-sphere"
  "github.com/gin-gonic/gin"
)

func main() {
    // create websocket server
    s := sphere.Default()
    // create http server
    r := gin.Default()
    // attach websocket handler
    r.GET("/sync", func(c *gin.Context) {
      s.Handler(c.Writer, c.Request)
    })
    // listen and serve on 0.0.0.0:8080
    r.Run(":8080") 
}

Scale websocket horizontally via pub/sub (broker) synchronization

b := sphere.DefaultRedisBroker()
s := sphere.Default(b) // <= pass in redis broker when creates websocket server

Use custom pubsub broker/agent

package main

import "github.com/samuelngs/go-sphere"

type MessageBroker struct {
	*sphere.Broker
}

func (broker *MessageBroker) OnSubscribe(channel *sphere.Channel, done chan<- sphere.IError) { }

func (broker *MessageBroker) OnUnsubscribe(channel *sphere.Channel, done chan<- sphere.IError) { }

func (broker *MessageBroker) OnPublish(channel *sphere.Channel, data *sphere.Packet) error {
	return nil
}

func (broker *MessageBroker) OnMessage(channel *sphere.Channel, data *sphere.Packet) error {
	return nil
}

func main() {
  customBroker := &MessageBroker{ExtendBroker()}
  s := sphere.Default(customBroker)
}

Custom channel events

package main

import "github.com/samuelngs/go-sphere"

// SphereUserAccount Model
type SphereUserAccount struct{}

// Namespace represents the namespace of the model
func (m *SphereUserAccount) Namespace() string {
	return "user-account"
}

// Subscribe decides whether accept the connection into channel or not, return true => accept, false => reject
func (m *SphereUserAccount) Subscribe(room string, connection *sphere.Connection) (bool, sphere.IError) {
	return true, nil
}

// Disconnect defines the action when user disconnect from channel
func (m *SphereUserAccount) Disconnect(room string, connection *sphere.Connection) sphere.IError {
	return nil
}

// Receive defines the action when websocket server receive message from user in this channel
func (m *SphereUserAccount) Receive(event string, message string) (string, sphere.IError) {
	return "", nil
}

func main() {
  s := sphere.Default()
  s.Models(&SphereUserAccount{})
}

Client-side

The sphere-client library can be found at https://github.com/samuelngs/sphere-client

Documentation

go doc format documentation for this project can be viewed online without installing the package by using the GoDoc page at: https://godoc.org/github.com/samuelngs/go-sphere

Contributing

Everyone is encouraged to help improve this project. Here are a few ways you can help:

License

This project is distributed under the MIT license found in the LICENSE file.

The MIT License (MIT)

Copyright (c) 2015 Samuel

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotFound         = &ProtocolError{"not found"}
	ErrNotSupported     = &ProtocolError{"not supported"}
	ErrNotImplemented   = &ProtocolError{"not implemented"}
	ErrTooManyRequest   = &ProtocolError{"too many requests"}
	ErrBadScheme        = &ProtocolError{"bad scheme"}
	ErrBadStatus        = &ProtocolError{"bad status"}
	ErrBadRequestMethod = &ProtocolError{"bad method"}
	ErrUnauthorized     = &ProtocolError{"unauthorized"}
	ErrServerErrors     = &ProtocolError{"server errors"}
	ErrRequestFailed    = &ProtocolError{"request failed"}

	ErrAlreadySubscribed = &ClientError{"already subscribed"}
	ErrNotSubscribed     = &ClientError{"not subscribed"}

	ErrPacketBadScheme = &PacketError{"packet bad scheme"}
	ErrPacketBadType   = &PacketError{"packet bad type"}
)

List of errors

View Source
var ChannelEventCode = [...]string{
	"subscribe",
	"unsubscribe",
	"subscribeFail",
}

ChannelEventCode returns the string value of ChannelEvent

View Source
var ChannelStateCode = [...]string{
	"subscribed",
	"unsubscribed",
	"pending",
}

ChannelStateCode returns the string value of ChannelState

View Source
var PacketTypeCode = [...]string{
	"message",
	"channel",
	"subscribe",
	"unsubscribe",
	"subscribed",
	"unsubscribed",
	"ping",
	"pong",
	"unknown",
}

PacketTypeCode returns the string value of SphereError

Functions

func LogError

func LogError(err IError)

LogError logs the function name, line and error message

func NewConnection

func NewConnection(upgrader websocket.Upgrader, w http.ResponseWriter, r *http.Request) (*Connection, IError)

NewConnection returns a new ws connection instance

Types

type Broker

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

Broker allows you to interact directly with Websocket internal data and pub/sub channels

func ExtendBroker

func ExtendBroker() *Broker

ExtendBroker creates a broker instance

func (*Broker) ChannelName

func (broker *Broker) ChannelName(namespace string, room string) string

ChannelName returns channel name with provided namespace and room name

func (*Broker) ID

func (broker *Broker) ID() string

ID returns the unique id for the broker

func (*Broker) IsSubscribed

func (broker *Broker) IsSubscribed(namespace string, room string) bool

IsSubscribed return the broker state of the channel

func (*Broker) OnMessage

func (broker *Broker) OnMessage(channel *Channel, data *Packet) error

OnMessage when websocket receive data from the broker subscriber

func (*Broker) OnPublish

func (broker *Broker) OnPublish(channel *Channel, data *Packet) error

OnPublish when websocket publishes data to a particular channel from the current broker

func (*Broker) OnSubscribe

func (broker *Broker) OnSubscribe(channel *Channel, done chan<- IError)

OnSubscribe when websocket subscribes to a channel

func (*Broker) OnUnsubscribe

func (broker *Broker) OnUnsubscribe(channel *Channel, done chan<- IError)

OnUnsubscribe when websocket unsubscribes from a channel

func (*Broker) Store

func (broker *Broker) Store() cmap.ConcurrentMap

Store returns the channel store

type Channel

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

Channel let you subscribe to and watch for incoming data which is published on that channel by other clients or the server

func NewChannel

func NewChannel(namespace string, room string) *Channel

NewChannel creates new Channel instance

func (*Channel) Connections

func (channel *Channel) Connections() []*Connection

Connections returns a list of active user connections

func (*Channel) Emit

func (channel *Channel) Emit(mt int, payload []byte, c *Connection) IError

Emit sends message to current channel

func (*Channel) Name

func (channel *Channel) Name() string

Name returns the name of the channel

func (*Channel) State

func (channel *Channel) State() ChannelState

State returns the state of the channel

type ChannelEvent

type ChannelEvent int

ChannelEvent indicates the state of the channel

const (
	// ChannelEventSubscribe indicates that this channel is in a subscribed state
	ChannelEventSubscribe ChannelEvent = iota
	// ChannelEventUnsubscribe indicates that this channel is in a unsubscribed state
	ChannelEventUnsubscribe
	// ChannelEventSubscribeFail indicates that this channel is in a pending state
	ChannelEventSubscribeFail
)

func (ChannelEvent) String

func (s ChannelEvent) String() string

Returns the code id of channel state

type ChannelModel

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

ChannelModel is for user to define channel events and actions

func ExtendChannelModel

func ExtendChannelModel(namespace string) *ChannelModel

ExtendChannelModel lets developer create a IChannals compatible struct

func (*ChannelModel) Disconnect

func (m *ChannelModel) Disconnect(room string, connection *Connection) IError

Disconnect defines the action when user disconnect from channel

func (*ChannelModel) Namespace

func (m *ChannelModel) Namespace() string

Namespace to return name of the channel

func (*ChannelModel) Receive

func (m *ChannelModel) Receive(event string, message string) (string, IError)

Receive defines the action when websocket server receive message from user in this channel

func (*ChannelModel) Subscribe

func (m *ChannelModel) Subscribe(room string, message *Message, connection *Connection) (bool, IError)

Subscribe decides whether accept the connection into channel or not, return true => accept, false => reject

type ChannelState

type ChannelState int

ChannelState indicates the state of the channel

const (
	// ChannelStateSubscribed indicates that this channel is in a subscribed state
	ChannelStateSubscribed ChannelState = iota
	// ChannelStateUnsubscribed indicates that this channel is in a unsubscribed state
	ChannelStateUnsubscribed
	// ChannelStatePending indicates that this channel is in a pending state
	ChannelStatePending
)

func (ChannelState) String

func (s ChannelState) String() string

Returns the code id of channel state

type ClientError

type ClientError Error

ClientError represents general client errors.

func (*ClientError) Error

func (e *ClientError) Error() string

Error returns error string of ChannelError

type Connection

type Connection struct {

	// websocket connection
	*websocket.Conn
	// contains filtered or unexported fields
}

Connection allows you to interact with backend and other client sockets in realtime

func (*Connection) Cookies

func (conn *Connection) Cookies() []*http.Cookie

Cookies export connection cookies

func (*Connection) Headers

func (conn *Connection) Headers() http.Header

Headers export connection headers

type Error

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

Error is a trivial implementation of error.

func (*Error) Error

func (e *Error) Error() string

Error returns error string of Error

type EventModel

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

EventModel is for user to define channel events and actions

func ExtendEventModel

func ExtendEventModel(namespace string) *EventModel

ExtendEventModel lets developer create a IEvents compatible struct

func (*EventModel) Namespace

func (m *EventModel) Namespace() string

Namespace to return name of the channel

func (*EventModel) Receive

func (m *EventModel) Receive(event string, message string) (string, IError)

Receive defines the action when websocket server receive message from user in this channel

type IBroker

type IBroker interface {
	ID() string                            // => Broker ID
	ChannelName(string, string) string     // => Broker generate channel name with namespace and channel
	IsSubscribed(string, string) bool      // => Broker channel subscribe state
	OnSubscribe(*Channel, chan<- IError)   // => Broker OnSubscribe
	OnUnsubscribe(*Channel, chan<- IError) // => Broker OnUnsubscribe
	OnPublish(*Channel, *Packet) error     // => Broker OnPublish
	OnMessage(*Channel, *Packet) error     // => Broker OnMessage
}

IBroker represents Broker instance

type IChannels

type IChannels interface {
	Namespace() string
	Subscribe(string, *Message, *Connection) (bool, IError)
	Disconnect(string, *Connection) IError
	Receive(string, string) (string, IError)
}

IChannels is the interface for ChannelModel

type IError

type IError interface {
	Error() string
}

IError interface

type IEvents

type IEvents interface {
	Namespace() string
	Receive(string, string) (string, IError)
}

IEvents represents EventModel

type Message

type Message struct {
	Event string `json:"event,omitempty"`
	Data  string `json:"data,omitempty"`
}

Message indicates the data of the message

type Option

type Option struct {
	CheckOrigin bool
}

Option for Sphere

type Packet

type Packet struct {
	Type      PacketType `json:"type"`
	Namespace string     `json:"namespace,omitempty"`
	Room      string     `json:"room,omitempty"`
	Cid       int        `json:"cid"`
	Error     error      `json:"error,omitempty"`
	Message   *Message   `json:"message,omitempty"`
	Reply     bool       `json:"reply"`
	Machine   string     `json:"-"`
}

Packet indicates the data of the message

func ParsePacket

func ParsePacket(data []byte) (*Packet, error)

ParsePacket returns Packet from bytes

func (*Packet) MarshalJSON

func (p *Packet) MarshalJSON() ([]byte, error)

MarshalJSON handler

func (*Packet) Response

func (p *Packet) Response() *Packet

Response return response packet

func (*Packet) SetError

func (p *Packet) SetError(err error) *Packet

SetError set error message

func (*Packet) String

func (p *Packet) String() string

String returns Packet in string format

func (*Packet) ToBytes

func (p *Packet) ToBytes() ([]byte, error)

ToBytes returns byte array from Packet

func (*Packet) ToJSON

func (p *Packet) ToJSON() ([]byte, error)

ToJSON returns json byte array from Packet

type PacketError

type PacketError Error

PacketError represents general client errors.

func (*PacketError) Error

func (e *PacketError) Error() string

Error returns error string of ChannelError

type PacketType

type PacketType int

PacketType indicates the error of the channel

const (
	// PacketTypeMessage denotes a regular text data message.
	PacketTypeMessage PacketType = iota
	// PacketTypeChannel denotes a channel request.
	PacketTypeChannel
	// PacketTypeSubscribe denotes a subscribe request.
	PacketTypeSubscribe
	// PacketTypeUnsubscribe denotes an unsubscribe request.
	PacketTypeUnsubscribe
	// PacketTypeSubscribed denotes a response of subscribe request.
	PacketTypeSubscribed
	// PacketTypeUnsubscribed denotes a response of unsubscribe request.
	PacketTypeUnsubscribed
	// PacketTypePing denotes an ping message.
	PacketTypePing
	// PacketTypePong denotes an pong message.
	PacketTypePong
	// PacketTypeUnknown denotes an pong message.
	PacketTypeUnknown
)

func (*PacketType) MarshalJSON

func (p *PacketType) MarshalJSON() ([]byte, error)

MarshalJSON to convert PacketType to json string

func (PacketType) String

func (p PacketType) String() string

Returns the error message

func (*PacketType) UnmarshalJSON

func (p *PacketType) UnmarshalJSON(b []byte) (err error)

UnmarshalJSON to parse object from json string

type ProtocolError

type ProtocolError Error

ProtocolError represents WebSocket protocol errors.

func (*ProtocolError) Error

func (e *ProtocolError) Error() string

Error returns error string of ProtocolError

type RedisBroker

type RedisBroker struct {
	*Broker
}

RedisBroker is a broker adapter built on Redis client

func DefaultRedisBroker

func DefaultRedisBroker() *RedisBroker

DefaultRedisBroker creates a new instance of RedisBroker

func (*RedisBroker) OnMessage

func (broker *RedisBroker) OnMessage(channel *Channel, data *Packet) error

OnMessage when websocket receive data from the broker subscriber

func (*RedisBroker) OnPublish

func (broker *RedisBroker) OnPublish(channel *Channel, data *Packet) error

OnPublish when websocket publishes data to a particular channel from the current broker

func (*RedisBroker) OnSubscribe

func (broker *RedisBroker) OnSubscribe(channel *Channel, done chan<- IError)

OnSubscribe when websocket subscribes to a channel

func (*RedisBroker) OnUnsubscribe

func (broker *RedisBroker) OnUnsubscribe(channel *Channel, done chan<- IError)

OnUnsubscribe when websocket unsubscribes from a channel

type SimpleBroker

type SimpleBroker struct {
	*Broker
}

SimpleBroker is a broker adapter built on Simple client

func DefaultSimpleBroker

func DefaultSimpleBroker() *SimpleBroker

DefaultSimpleBroker creates a new instance of SimpleBroker

func (*SimpleBroker) OnMessage

func (broker *SimpleBroker) OnMessage(channel *Channel, data *Packet) error

OnMessage when websocket receive data from the broker subscriber

func (*SimpleBroker) OnPublish

func (broker *SimpleBroker) OnPublish(channel *Channel, data *Packet) error

OnPublish when websocket publishes data to a particular channel from the current broker

func (*SimpleBroker) OnSubscribe

func (broker *SimpleBroker) OnSubscribe(channel *Channel, done chan<- IError)

OnSubscribe when websocket subscribes to a channel

func (*SimpleBroker) OnUnsubscribe

func (broker *SimpleBroker) OnUnsubscribe(channel *Channel, done chan<- IError)

OnUnsubscribe when websocket unsubscribes from a channel

type Sphere

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

Sphere represents an entire Websocket instance

func Default

func Default(opts ...interface{}) *Sphere

Default creates a new instance of Sphere

func (*Sphere) Handler

func (sphere *Sphere) Handler(w http.ResponseWriter, r *http.Request) IError

Handler handles and creates websocket connection

func (*Sphere) Models

func (sphere *Sphere) Models(models ...interface{})

Models load channel or event models

Jump to

Keyboard shortcuts

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