There is no reason to export this functions and this types.
This commit is contained in:
+22
-22
@@ -14,7 +14,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// An App
|
// An App
|
||||||
type App struct {
|
type app struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
|
|
||||||
Name string
|
Name string
|
||||||
@@ -27,22 +27,22 @@ type App struct {
|
|||||||
WebHooks bool
|
WebHooks bool
|
||||||
URLWebHook string
|
URLWebHook string
|
||||||
|
|
||||||
Channels map[string]*Channel `json:"-"`
|
Channels map[string]*channel `json:"-"`
|
||||||
Connections map[string]*Connection `json:"-"`
|
Connections map[string]*connection `json:"-"`
|
||||||
|
|
||||||
Stats *expvar.Map `json:"-"`
|
Stats *expvar.Map `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alloc memory for Connections and Channels
|
// Alloc memory for Connections and Channels
|
||||||
func (a *App) Init() {
|
func (a *app) Init() {
|
||||||
a.Connections = make(map[string]*Connection)
|
a.Connections = make(map[string]*connection)
|
||||||
a.Channels = make(map[string]*Channel)
|
a.Channels = make(map[string]*channel)
|
||||||
a.Stats = expvar.NewMap(fmt.Sprintf("%s (%s)", a.Name, a.AppID))
|
a.Stats = expvar.NewMap(fmt.Sprintf("%s (%s)", a.Name, a.AppID))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only Presence channels
|
// Only Presence channels
|
||||||
func (a *App) PresenceChannels() []*Channel {
|
func (a *app) PresenceChannels() []*channel {
|
||||||
var channels []*Channel
|
var channels []*channel
|
||||||
|
|
||||||
for _, c := range a.Channels {
|
for _, c := range a.Channels {
|
||||||
if c.IsPresence() {
|
if c.IsPresence() {
|
||||||
@@ -54,8 +54,8 @@ func (a *App) PresenceChannels() []*Channel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only Private channels
|
// Only Private channels
|
||||||
func (a *App) PrivateChannels() []*Channel {
|
func (a *app) PrivateChannels() []*channel {
|
||||||
var channels []*Channel
|
var channels []*channel
|
||||||
|
|
||||||
for _, c := range a.Channels {
|
for _, c := range a.Channels {
|
||||||
if c.IsPrivate() {
|
if c.IsPrivate() {
|
||||||
@@ -67,8 +67,8 @@ func (a *App) PrivateChannels() []*Channel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only Public channels
|
// Only Public channels
|
||||||
func (a *App) PublicChannels() []*Channel {
|
func (a *app) PublicChannels() []*channel {
|
||||||
var channels []*Channel
|
var channels []*channel
|
||||||
|
|
||||||
for _, c := range a.Channels {
|
for _, c := range a.Channels {
|
||||||
if c.IsPublic() {
|
if c.IsPublic() {
|
||||||
@@ -80,7 +80,7 @@ func (a *App) PublicChannels() []*Channel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Disconnect Socket
|
// Disconnect Socket
|
||||||
func (a *App) Disconnect(socketID string) {
|
func (a *app) Disconnect(socketID string) {
|
||||||
log.Infof("Disconnecting socket %+v", socketID)
|
log.Infof("Disconnecting socket %+v", socketID)
|
||||||
|
|
||||||
conn, err := a.FindConnection(socketID)
|
conn, err := a.FindConnection(socketID)
|
||||||
@@ -113,7 +113,7 @@ func (a *App) Disconnect(socketID string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Connect a new Subscriber
|
// Connect a new Subscriber
|
||||||
func (a *App) Connect(conn *Connection) {
|
func (a *app) Connect(conn *connection) {
|
||||||
log.Infof("Adding a new Connection %s to app %s", conn.SocketID, a.Name)
|
log.Infof("Adding a new Connection %s to app %s", conn.SocketID, a.Name)
|
||||||
a.Lock()
|
a.Lock()
|
||||||
defer a.Unlock()
|
defer a.Unlock()
|
||||||
@@ -124,7 +124,7 @@ func (a *App) Connect(conn *Connection) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find a Connection on this app
|
// Find a Connection on this app
|
||||||
func (a *App) FindConnection(socketID string) (*Connection, error) {
|
func (a *app) FindConnection(socketID string) (*connection, error) {
|
||||||
conn, exists := a.Connections[socketID]
|
conn, exists := a.Connections[socketID]
|
||||||
|
|
||||||
if exists {
|
if exists {
|
||||||
@@ -135,7 +135,7 @@ func (a *App) FindConnection(socketID string) (*Connection, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DeleteChannel removes the channel from app
|
// DeleteChannel removes the channel from app
|
||||||
func (a *App) RemoveChannel(c *Channel) {
|
func (a *app) RemoveChannel(c *channel) {
|
||||||
log.Infof("Remove the channel %s from app %s", c.ChannelID, a.Name)
|
log.Infof("Remove the channel %s from app %s", c.ChannelID, a.Name)
|
||||||
a.Lock()
|
a.Lock()
|
||||||
defer a.Unlock()
|
defer a.Unlock()
|
||||||
@@ -158,7 +158,7 @@ func (a *App) RemoveChannel(c *Channel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add a new Channel to this APP
|
// Add a new Channel to this APP
|
||||||
func (a *App) AddChannel(c *Channel) {
|
func (a *app) AddChannel(c *channel) {
|
||||||
log.Infof("Adding a new channel %s to app %s", c.ChannelID, a.Name)
|
log.Infof("Adding a new channel %s to app %s", c.ChannelID, a.Name)
|
||||||
|
|
||||||
a.Lock()
|
a.Lock()
|
||||||
@@ -183,7 +183,7 @@ func (a *App) AddChannel(c *Channel) {
|
|||||||
|
|
||||||
// Returns a Channel from this app
|
// Returns a Channel from this app
|
||||||
// If not found then the channel is created and added to this app
|
// If not found then the channel is created and added to this app
|
||||||
func (a *App) FindOrCreateChannelByChannelID(n string) *Channel {
|
func (a *app) FindOrCreateChannelByChannelID(n string) *channel {
|
||||||
c, err := a.FindChannelByChannelID(n)
|
c, err := a.FindChannelByChannelID(n)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -195,7 +195,7 @@ func (a *App) FindOrCreateChannelByChannelID(n string) *Channel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find the channel by channel ID
|
// Find the channel by channel ID
|
||||||
func (a *App) FindChannelByChannelID(n string) (*Channel, error) {
|
func (a *app) FindChannelByChannelID(n string) (*channel, error) {
|
||||||
c, exists := a.Channels[n]
|
c, exists := a.Channels[n]
|
||||||
|
|
||||||
if exists {
|
if exists {
|
||||||
@@ -205,16 +205,16 @@ func (a *App) FindChannelByChannelID(n string) (*Channel, error) {
|
|||||||
return nil, errors.New("Channel does not exists")
|
return nil, errors.New("Channel does not exists")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) Publish(c *Channel, event RawEvent, ignore string) error {
|
func (a *app) Publish(c *channel, event rawEvent, ignore string) error {
|
||||||
a.Stats.Add("TotalUniqueMessages", 1)
|
a.Stats.Add("TotalUniqueMessages", 1)
|
||||||
|
|
||||||
return c.Publish(a, event, ignore)
|
return c.Publish(a, event, ignore)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) Unsubscribe(c *Channel, conn *Connection) error {
|
func (a *app) Unsubscribe(c *channel, conn *connection) error {
|
||||||
return c.Unsubscribe(a, conn)
|
return c.Unsubscribe(a, conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) Subscribe(c *Channel, conn *Connection, data string) error {
|
func (a *app) Subscribe(c *channel, conn *connection, data string) error {
|
||||||
return c.Subscribe(a, conn, data)
|
return c.Subscribe(a, conn, data)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -11,9 +11,9 @@ import (
|
|||||||
|
|
||||||
var id = 0
|
var id = 0
|
||||||
|
|
||||||
func newApp() *App {
|
func newApp() *app {
|
||||||
|
|
||||||
a := App{Name: "Test", AppID: strconv.Itoa(id), Key: "123", Secret: "123", OnlySSL: false, ApplicationDisabled: false, UserEvents: true}
|
a := app{Name: "Test", AppID: strconv.Itoa(id), Key: "123", Secret: "123", OnlySSL: false, ApplicationDisabled: false, UserEvents: true}
|
||||||
a.Init()
|
a.Init()
|
||||||
|
|
||||||
id++
|
id++
|
||||||
|
|||||||
+18
-18
@@ -15,46 +15,46 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// A Channel
|
// A Channel
|
||||||
type Channel struct {
|
type channel struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
|
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
ChannelID string
|
ChannelID string
|
||||||
Subscriptions map[string]*Subscription
|
Subscriptions map[string]*subscription
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if the channel has at least one subscriber
|
// Return true if the channel has at least one subscriber
|
||||||
func (c *Channel) IsOccupied() bool {
|
func (c *channel) IsOccupied() bool {
|
||||||
return c.TotalSubscriptions() > 0
|
return c.TotalSubscriptions() > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the type of the channel is presence or is private
|
// Check if the type of the channel is presence or is private
|
||||||
func (c *Channel) IsPresenceOrPrivate() bool {
|
func (c *channel) IsPresenceOrPrivate() bool {
|
||||||
return c.IsPresence() || c.IsPrivate()
|
return c.IsPresence() || c.IsPrivate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the type of the channel is public
|
// Check if the type of the channel is public
|
||||||
func (c *Channel) IsPublic() bool {
|
func (c *channel) IsPublic() bool {
|
||||||
return !c.IsPresenceOrPrivate()
|
return !c.IsPresenceOrPrivate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the type of the channel is presence
|
// Check if the type of the channel is presence
|
||||||
func (c *Channel) IsPresence() bool {
|
func (c *channel) IsPresence() bool {
|
||||||
return strings.HasPrefix(c.ChannelID, "presence-")
|
return strings.HasPrefix(c.ChannelID, "presence-")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the type of the channel is private
|
// Check if the type of the channel is private
|
||||||
func (c *Channel) IsPrivate() bool {
|
func (c *channel) IsPrivate() bool {
|
||||||
return strings.HasPrefix(c.ChannelID, "private-")
|
return strings.HasPrefix(c.ChannelID, "private-")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the total of subscribers
|
// Get the total of subscribers
|
||||||
func (c *Channel) TotalSubscriptions() int {
|
func (c *channel) TotalSubscriptions() int {
|
||||||
return len(c.Subscriptions)
|
return len(c.Subscriptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the total of users.
|
// Get the total of users.
|
||||||
func (c *Channel) TotalUsers() int {
|
func (c *channel) TotalUsers() int {
|
||||||
total := make(map[string]int)
|
total := make(map[string]int)
|
||||||
|
|
||||||
for _, s := range c.Subscriptions {
|
for _, s := range c.Subscriptions {
|
||||||
@@ -65,7 +65,7 @@ func (c *Channel) TotalUsers() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add a new subscriber to the channel
|
// Add a new subscriber to the channel
|
||||||
func (c *Channel) Subscribe(a *App, conn *Connection, channelData string) error {
|
func (c *channel) Subscribe(a *app, conn *connection, channelData string) error {
|
||||||
log.Infof("Subscribing %s to channel %s", conn.SocketID, c.ChannelID)
|
log.Infof("Subscribing %s to channel %s", conn.SocketID, c.ChannelID)
|
||||||
|
|
||||||
c.Lock()
|
c.Lock()
|
||||||
@@ -105,7 +105,7 @@ func (c *Channel) Subscribe(a *App, conn *Connection, channelData string) error
|
|||||||
a.TriggerMemberAddedHook(c, subscription)
|
a.TriggerMemberAddedHook(c, subscription)
|
||||||
|
|
||||||
// pusher_internal:subscription_succeeded
|
// pusher_internal:subscription_succeeded
|
||||||
data := make(map[string]SubscriptionSucceeedEventPresenceData)
|
data := make(map[string]subscriptionSucceeedEventPresenceData)
|
||||||
data["presence"] = newSubscriptionSucceedEventPresenceData(c)
|
data["presence"] = newSubscriptionSucceedEventPresenceData(c)
|
||||||
|
|
||||||
js, err = json.Marshal(data)
|
js, err = json.Marshal(data)
|
||||||
@@ -129,14 +129,14 @@ func (c *Channel) Subscribe(a *App, conn *Connection, channelData string) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IsSubscribed check if the user is subscribed
|
// IsSubscribed check if the user is subscribed
|
||||||
func (c *Channel) IsSubscribed(conn *Connection) bool {
|
func (c *channel) IsSubscribed(conn *connection) bool {
|
||||||
_, exists := c.Subscriptions[conn.SocketID]
|
_, exists := c.Subscriptions[conn.SocketID]
|
||||||
return exists
|
return exists
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the subscriber from the channel
|
// Remove the subscriber from the channel
|
||||||
// It destroy the channel if the channels does not have any subscribers.
|
// It destroy the channel if the channels does not have any subscribers.
|
||||||
func (c *Channel) Unsubscribe(a *App, conn *Connection) error {
|
func (c *channel) Unsubscribe(a *app, conn *connection) error {
|
||||||
log.Infof("Unsubscribing %s from channel %s", conn.SocketID, c.ChannelID)
|
log.Infof("Unsubscribing %s from channel %s", conn.SocketID, c.ChannelID)
|
||||||
|
|
||||||
c.Lock()
|
c.Lock()
|
||||||
@@ -169,14 +169,14 @@ func (c *Channel) Unsubscribe(a *App, conn *Connection) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new Channel
|
// Create a new Channel
|
||||||
func newChannel(channelID string) *Channel {
|
func newChannel(channelID string) *channel {
|
||||||
log.Infof("Creating a new channel: %s", channelID)
|
log.Infof("Creating a new channel: %s", channelID)
|
||||||
|
|
||||||
return &Channel{ChannelID: channelID, CreatedAt: time.Now(), Subscriptions: make(map[string]*Subscription)}
|
return &channel{ChannelID: channelID, CreatedAt: time.Now(), Subscriptions: make(map[string]*subscription)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publish a MemberAddedEvent to all subscriptions
|
// Publish a MemberAddedEvent to all subscriptions
|
||||||
func (c *Channel) PublishMemberAddedEvent(a *App, data string, subscription *Subscription) {
|
func (c *channel) PublishMemberAddedEvent(a *app, data string, subscription *subscription) {
|
||||||
for _, subs := range c.Subscriptions {
|
for _, subs := range c.Subscriptions {
|
||||||
if subs != subscription {
|
if subs != subscription {
|
||||||
subs.Connection.Publish(newMemberAddedEvent(c.ChannelID, data))
|
subs.Connection.Publish(newMemberAddedEvent(c.ChannelID, data))
|
||||||
@@ -185,7 +185,7 @@ func (c *Channel) PublishMemberAddedEvent(a *App, data string, subscription *Sub
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Publish a MemberRemovedEvent to all subscriptions
|
// Publish a MemberRemovedEvent to all subscriptions
|
||||||
func (c *Channel) PublishMemberRemovedEvent(a *App, subscription *Subscription) {
|
func (c *channel) PublishMemberRemovedEvent(a *app, subscription *subscription) {
|
||||||
for _, subs := range c.Subscriptions {
|
for _, subs := range c.Subscriptions {
|
||||||
if subs != subscription {
|
if subs != subscription {
|
||||||
subs.Connection.Publish(newMemberRemovedEvent(c.ChannelID, subscription))
|
subs.Connection.Publish(newMemberRemovedEvent(c.ChannelID, subscription))
|
||||||
@@ -194,7 +194,7 @@ func (c *Channel) PublishMemberRemovedEvent(a *App, subscription *Subscription)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Publish messages to all Subscribers
|
// Publish messages to all Subscribers
|
||||||
func (c *Channel) Publish(a *App, event RawEvent, ignore string) error {
|
func (c *channel) Publish(a *app, event rawEvent, ignore string) error {
|
||||||
b, err := event.Data.MarshalJSON()
|
b, err := event.Data.MarshalJSON()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+14
-14
@@ -10,44 +10,44 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// The config file
|
// The config file
|
||||||
type ConfigFile struct {
|
type configFile struct {
|
||||||
Host string // The host, eg: :8080 will start on 0.0.0.0:8080
|
Host string // The host, eg: :8080 will start on 0.0.0.0:8080
|
||||||
Expvar bool
|
Expvar bool
|
||||||
User string
|
User string
|
||||||
Password string
|
Password string
|
||||||
Apps []*App
|
Apps []*app
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error for App not found
|
// Error for App not found
|
||||||
var AppNotFoundError = errors.New("App not found")
|
var AppNotFoundError = errors.New("App not found")
|
||||||
|
|
||||||
// Initialize Apps
|
// Initialize Apps
|
||||||
func (c *ConfigFile) Init() {
|
func (c *configFile) Init() {
|
||||||
for _, app := range c.Apps {
|
for _, app := range c.Apps {
|
||||||
app.Init()
|
app.Init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConfigFile) WasProvidedUserAndPassword() bool {
|
func (c *configFile) WasProvidedUserAndPassword() bool {
|
||||||
return len(strings.TrimSpace(c.User)) > 0 && len(strings.TrimSpace(c.Password)) > 0
|
return len(strings.TrimSpace(c.User)) > 0 && len(strings.TrimSpace(c.Password)) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns an App with by appID
|
// Returns an App with by appID
|
||||||
func (c *ConfigFile) GetAppByAppID(appID string) (*App, error) {
|
func (c *configFile) GetAppByAppID(appID string) (*app, error) {
|
||||||
for _, app := range c.Apps {
|
for _, a := range c.Apps {
|
||||||
if app.AppID == appID {
|
if a.AppID == appID {
|
||||||
return app, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &App{}, AppNotFoundError
|
return &app{}, AppNotFoundError
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns an App with by key
|
// Returns an App with by key
|
||||||
func (c *ConfigFile) GetAppByKey(key string) (*App, error) {
|
func (c *configFile) GetAppByKey(key string) (*app, error) {
|
||||||
for _, app := range c.Apps {
|
for _, a := range c.Apps {
|
||||||
if app.Key == key {
|
if a.Key == key {
|
||||||
return app, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &App{}, AppNotFoundError
|
return &app{}, AppNotFoundError
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -10,20 +10,20 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// An User Connection
|
// An User Connection
|
||||||
type Connection struct {
|
type connection struct {
|
||||||
SocketID string
|
SocketID string
|
||||||
Socket *websocket.Conn
|
Socket *websocket.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new Subscriber
|
// Create a new Subscriber
|
||||||
func newConnection(socketID string, s *websocket.Conn) *Connection {
|
func newConnection(socketID string, s *websocket.Conn) *connection {
|
||||||
log.Infof("Creating a new Subscriber %+v", socketID)
|
log.Infof("Creating a new Subscriber %+v", socketID)
|
||||||
|
|
||||||
return &Connection{SocketID: socketID, Socket: s}
|
return &connection{SocketID: socketID, Socket: s}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publish the message to websocket atached to this client
|
// Publish the message to websocket atached to this client
|
||||||
func (conn *Connection) Publish(m interface{}) {
|
func (conn *connection) Publish(m interface{}) {
|
||||||
go func() {
|
go func() {
|
||||||
if err := conn.Socket.WriteJSON(m); err != nil {
|
if err := conn.Socket.WriteJSON(m); err != nil {
|
||||||
log.Errorf("Error publishing message to connection %+v, %s", conn, err)
|
log.Errorf("Error publishing message to connection %+v, %s", conn, err)
|
||||||
|
|||||||
+44
-44
@@ -5,114 +5,114 @@
|
|||||||
package ipe
|
package ipe
|
||||||
|
|
||||||
// Base interface
|
// Base interface
|
||||||
type WebsocketError interface {
|
type websocketError interface {
|
||||||
GetCode() int
|
GetCode() int
|
||||||
GetMsg() string
|
GetMsg() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base struct
|
// Base struct
|
||||||
type BaseWebsocketError struct {
|
type baseWebsocketError struct {
|
||||||
Code int
|
Code int
|
||||||
Msg string
|
Msg string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e BaseWebsocketError) GetCode() int {
|
func (e baseWebsocketError) GetCode() int {
|
||||||
return e.Code
|
return e.Code
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e BaseWebsocketError) GetMsg() string {
|
func (e baseWebsocketError) GetMsg() string {
|
||||||
return e.Msg
|
return e.Msg
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unsupprted protocol version
|
// Unsupprted protocol version
|
||||||
type UnsupportedProtocolVersionError struct {
|
type unsupportedProtocolVersionError struct {
|
||||||
BaseWebsocketError
|
baseWebsocketError
|
||||||
}
|
}
|
||||||
|
|
||||||
func newUnsupportedProtocolVersionError() UnsupportedProtocolVersionError {
|
func newUnsupportedProtocolVersionError() unsupportedProtocolVersionError {
|
||||||
return UnsupportedProtocolVersionError{
|
return unsupportedProtocolVersionError{
|
||||||
BaseWebsocketError{Code: UNSUPPORTED_PROTOCOL_VERSION, Msg: "Unsupported protocol version"},
|
baseWebsocketError{Code: UNSUPPORTED_PROTOCOL_VERSION, Msg: "Unsupported protocol version"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The application does not exists
|
// The application does not exists
|
||||||
// See the configuration file
|
// See the configuration file
|
||||||
type ApplicationDoesNotExistsError struct {
|
type applicationDoesNotExistsError struct {
|
||||||
BaseWebsocketError
|
baseWebsocketError
|
||||||
}
|
}
|
||||||
|
|
||||||
func newApplicationDoesNotExistsError() ApplicationDoesNotExistsError {
|
func newApplicationDoesNotExistsError() applicationDoesNotExistsError {
|
||||||
return ApplicationDoesNotExistsError{
|
return applicationDoesNotExistsError{
|
||||||
BaseWebsocketError{Code: APPLICATION_DOES_NOT_EXISTS, Msg: "Could not found an app with the given key"},
|
baseWebsocketError{Code: APPLICATION_DOES_NOT_EXISTS, Msg: "Could not found an app with the given key"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The user did not send the protocol version
|
// The user did not send the protocol version
|
||||||
type NoProtocolVersionSuppliedError struct {
|
type noProtocolVersionSuppliedError struct {
|
||||||
BaseWebsocketError
|
baseWebsocketError
|
||||||
}
|
}
|
||||||
|
|
||||||
func newNoProtocolVersionSuppliedError() NoProtocolVersionSuppliedError {
|
func newNoProtocolVersionSuppliedError() noProtocolVersionSuppliedError {
|
||||||
return NoProtocolVersionSuppliedError{
|
return noProtocolVersionSuppliedError{
|
||||||
BaseWebsocketError{Code: NO_PROTOCOL_VERSION_SUPPLIED, Msg: "No protocol version supplied"},
|
baseWebsocketError{Code: NO_PROTOCOL_VERSION_SUPPLIED, Msg: "No protocol version supplied"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the application is disabled.
|
// When the application is disabled.
|
||||||
// See the configuration file
|
// See the configuration file
|
||||||
type ApplicationDisabledError struct {
|
type applicationDisabledError struct {
|
||||||
BaseWebsocketError
|
baseWebsocketError
|
||||||
}
|
}
|
||||||
|
|
||||||
func newApplicationDisabledError() NoProtocolVersionSuppliedError {
|
func newApplicationDisabledError() noProtocolVersionSuppliedError {
|
||||||
return NoProtocolVersionSuppliedError{
|
return noProtocolVersionSuppliedError{
|
||||||
BaseWebsocketError{Code: APPLICATION_DISABLED, Msg: "Application disabled"},
|
baseWebsocketError{Code: APPLICATION_DISABLED, Msg: "Application disabled"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the application only accepts SSL connections
|
// When the application only accepts SSL connections
|
||||||
type ApplicationOnlyAccepsSSLError struct {
|
type applicationOnlyAccepsSSLError struct {
|
||||||
BaseWebsocketError
|
baseWebsocketError
|
||||||
}
|
}
|
||||||
|
|
||||||
func newApplicationOnlyAccepsSSLError() ApplicationOnlyAccepsSSLError {
|
func newApplicationOnlyAccepsSSLError() applicationOnlyAccepsSSLError {
|
||||||
return ApplicationOnlyAccepsSSLError{
|
return applicationOnlyAccepsSSLError{
|
||||||
BaseWebsocketError{Code: APPLICATION_ONLY_ACCEPTS_SSL, Msg: "Application only accepts SSL connections, reconnect using wss://"},
|
baseWebsocketError{Code: APPLICATION_ONLY_ACCEPTS_SSL, Msg: "Application only accepts SSL connections, reconnect using wss://"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the user send an invalid version
|
// When the user send an invalid version
|
||||||
type InvalidVersionStringFormatError struct {
|
type invalidVersionStringFormatError struct {
|
||||||
BaseWebsocketError
|
baseWebsocketError
|
||||||
}
|
}
|
||||||
|
|
||||||
func newInvalidVersionStringFormatError() InvalidVersionStringFormatError {
|
func newInvalidVersionStringFormatError() invalidVersionStringFormatError {
|
||||||
return InvalidVersionStringFormatError{
|
return invalidVersionStringFormatError{
|
||||||
BaseWebsocketError{Code: INVALID_VERSION_STRING_FORMAT, Msg: "Invalid version string format"},
|
baseWebsocketError{Code: INVALID_VERSION_STRING_FORMAT, Msg: "Invalid version string format"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used when the error was internal
|
// Used when the error was internal
|
||||||
// * Decoding json
|
// * Decoding json
|
||||||
// * Writing to output
|
// * Writing to output
|
||||||
type GenericReconnectImmediatelyError struct {
|
type genericReconnectImmediatelyError struct {
|
||||||
BaseWebsocketError
|
baseWebsocketError
|
||||||
}
|
}
|
||||||
|
|
||||||
func newGenericReconnectImmediatelyError() GenericReconnectImmediatelyError {
|
func newGenericReconnectImmediatelyError() genericReconnectImmediatelyError {
|
||||||
return GenericReconnectImmediatelyError{
|
return genericReconnectImmediatelyError{
|
||||||
BaseWebsocketError{Code: GENERIC_RECONNECT_IMMEDIATELY, Msg: "Generic reconnect immediately"},
|
baseWebsocketError{Code: GENERIC_RECONNECT_IMMEDIATELY, Msg: "Generic reconnect immediately"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When pusher wants to send an Generic error, it only send the message, the code become nil
|
// When pusher wants to send an Generic error, it only send the message, the code become nil
|
||||||
// Currently I do not know how to send nil, so I send GENERIC_ERROR
|
// Currently I do not know how to send nil, so I send GENERIC_ERROR
|
||||||
type GenericError struct {
|
type genericError struct {
|
||||||
BaseWebsocketError
|
baseWebsocketError
|
||||||
}
|
}
|
||||||
|
|
||||||
func newGenericError(msg string) GenericError {
|
func newGenericError(msg string) genericError {
|
||||||
return GenericError{
|
return genericError{
|
||||||
BaseWebsocketError{Code: GENERIC_ERROR, Msg: msg},
|
baseWebsocketError{Code: GENERIC_ERROR, Msg: msg},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+42
-42
@@ -18,24 +18,24 @@ import (
|
|||||||
// "channelData": "extra data"
|
// "channelData": "extra data"
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
type SubscribeEventData struct {
|
type subscribeEventData struct {
|
||||||
Channel string `json:"channel"`
|
Channel string `json:"channel"`
|
||||||
Auth string `json:"auth,omitempty"`
|
Auth string `json:"auth,omitempty"`
|
||||||
ChannelData string `json:"channel_data,omitempty"`
|
ChannelData string `json:"channel_data,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SubscribeEvent struct {
|
type subscribeEvent struct {
|
||||||
Event string `json:"event"`
|
Event string `json:"event"`
|
||||||
Data SubscribeEventData `json:"data"`
|
Data subscribeEventData `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new subscribe event with the specified channel and data
|
// Create a new subscribe event with the specified channel and data
|
||||||
func newSubscribeEvent(channel, auth, channelData string) SubscribeEvent {
|
func newSubscribeEvent(channel, auth, channelData string) subscribeEvent {
|
||||||
data := SubscribeEventData{Channel: channel, Auth: auth, ChannelData: channelData}
|
data := subscribeEventData{Channel: channel, Auth: auth, ChannelData: channelData}
|
||||||
return SubscribeEvent{Event: "pusher:subscribe", Data: data}
|
return subscribeEvent{Event: "pusher:subscribe", Data: data}
|
||||||
}
|
}
|
||||||
|
|
||||||
type UnsubscribeEventData struct {
|
type unsubscribeEventData struct {
|
||||||
Channel string `json:"channel"`
|
Channel string `json:"channel"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,30 +45,30 @@ type UnsubscribeEventData struct {
|
|||||||
// "channel": "The channel"
|
// "channel": "The channel"
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
type UnsubscribeEvent struct {
|
type unsubscribeEvent struct {
|
||||||
Event string `json:"event"`
|
Event string `json:"event"`
|
||||||
Data UnsubscribeEventData `json:"data"`
|
Data unsubscribeEventData `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new unsubscribe event for the specified channel
|
// Create a new unsubscribe event for the specified channel
|
||||||
func newUnsubscribeEvent(channel string) UnsubscribeEvent {
|
func newUnsubscribeEvent(channel string) unsubscribeEvent {
|
||||||
data := UnsubscribeEventData{Channel: channel}
|
data := unsubscribeEventData{Channel: channel}
|
||||||
return UnsubscribeEvent{Event: "pusher:unsubscribe", Data: data}
|
return unsubscribeEvent{Event: "pusher:unsubscribe", Data: data}
|
||||||
}
|
}
|
||||||
|
|
||||||
// {
|
// {
|
||||||
// "event": "pusher_internal:subscription_succeeded",
|
// "event": "pusher_internal:subscription_succeeded",
|
||||||
// "channel": "the channel"
|
// "channel": "the channel"
|
||||||
// }
|
// }
|
||||||
type SubscriptionSucceededEvent struct {
|
type subscriptionSucceededEvent struct {
|
||||||
Event string `json:"event"`
|
Event string `json:"event"`
|
||||||
Channel string `json:"channel"`
|
Channel string `json:"channel"`
|
||||||
Data string `json:"data"`
|
Data string `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new subscription succeed event for the specified channel
|
// Create a new subscription succeed event for the specified channel
|
||||||
func newSubscriptionSucceededEvent(channel, data string) SubscriptionSucceededEvent {
|
func newSubscriptionSucceededEvent(channel, data string) subscriptionSucceededEvent {
|
||||||
return SubscriptionSucceededEvent{Event: "pusher_internal:subscription_succeeded", Channel: channel, Data: data}
|
return subscriptionSucceededEvent{Event: "pusher_internal:subscription_succeeded", Channel: channel, Data: data}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data Subscription Succeed
|
// Data Subscription Succeed
|
||||||
@@ -89,14 +89,14 @@ func newSubscriptionSucceededEvent(channel, data string) SubscriptionSucceededEv
|
|||||||
// \"count\": 2
|
// \"count\": 2
|
||||||
// }
|
// }
|
||||||
// }"
|
// }"
|
||||||
type SubscriptionSucceeedEventPresenceData struct {
|
type subscriptionSucceeedEventPresenceData struct {
|
||||||
Ids []string `json:"ids"`
|
Ids []string `json:"ids"`
|
||||||
Hash map[string]interface{} `json:"hash"`
|
Hash map[string]interface{} `json:"hash"`
|
||||||
Count int `json:"count"`
|
Count int `json:"count"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSubscriptionSucceedEventPresenceData(c *Channel) SubscriptionSucceeedEventPresenceData {
|
func newSubscriptionSucceedEventPresenceData(c *channel) subscriptionSucceeedEventPresenceData {
|
||||||
event := SubscriptionSucceeedEventPresenceData{}
|
event := subscriptionSucceeedEventPresenceData{}
|
||||||
|
|
||||||
var ids []string
|
var ids []string
|
||||||
hash := make(map[string]interface{}, c.TotalSubscriptions())
|
hash := make(map[string]interface{}, c.TotalSubscriptions())
|
||||||
@@ -121,28 +121,28 @@ func newSubscriptionSucceedEventPresenceData(c *Channel) SubscriptionSucceeedEve
|
|||||||
// "event": "pusher:pong",
|
// "event": "pusher:pong",
|
||||||
// "data": {}
|
// "data": {}
|
||||||
// }
|
// }
|
||||||
type PongEvent struct {
|
type pongEvent struct {
|
||||||
Event string `json:"event"`
|
Event string `json:"event"`
|
||||||
Data string `json:"data"`
|
Data string `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new pong event
|
// Create a new pong event
|
||||||
func newPongEvent() PongEvent {
|
func newPongEvent() pongEvent {
|
||||||
return PongEvent{Event: "pusher:pong", Data: "{}"}
|
return pongEvent{Event: "pusher:pong", Data: "{}"}
|
||||||
}
|
}
|
||||||
|
|
||||||
// {
|
// {
|
||||||
// "event": "pusher:ping",
|
// "event": "pusher:ping",
|
||||||
// "data": {}
|
// "data": {}
|
||||||
// }
|
// }
|
||||||
type PingEvent struct {
|
type pingEvent struct {
|
||||||
Event string `json:"event"`
|
Event string `json:"event"`
|
||||||
Data string `json:"data"`
|
Data string `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new ping event
|
// Create a new ping event
|
||||||
func newPingEvent() PingEvent {
|
func newPingEvent() pingEvent {
|
||||||
return PingEvent{Event: "pusher:ping", Data: "{}"}
|
return pingEvent{Event: "pusher:ping", Data: "{}"}
|
||||||
}
|
}
|
||||||
|
|
||||||
// {
|
// {
|
||||||
@@ -152,7 +152,7 @@ func newPingEvent() PingEvent {
|
|||||||
// "code": 4000
|
// "code": 4000
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
type ErrorEvent struct {
|
type errorEvent struct {
|
||||||
Event string `json:"event"`
|
Event string `json:"event"`
|
||||||
Data interface{} `json:"data"`
|
Data interface{} `json:"data"`
|
||||||
}
|
}
|
||||||
@@ -161,7 +161,7 @@ type ErrorEvent struct {
|
|||||||
// Pusher protocol is very strange in some parts
|
// Pusher protocol is very strange in some parts
|
||||||
// It send null in some errors.
|
// It send null in some errors.
|
||||||
// So I created this GENERIC_ERROR thing, just to verify if the json must have null on the error code
|
// So I created this GENERIC_ERROR thing, just to verify if the json must have null on the error code
|
||||||
func newErrorEvent(code int, message string) ErrorEvent {
|
func newErrorEvent(code int, message string) errorEvent {
|
||||||
var data interface{}
|
var data interface{}
|
||||||
|
|
||||||
if code == GENERIC_ERROR {
|
if code == GENERIC_ERROR {
|
||||||
@@ -182,7 +182,7 @@ func newErrorEvent(code int, message string) ErrorEvent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ErrorEvent{Event: "pusher:error", Data: data}
|
return errorEvent{Event: "pusher:error", Data: data}
|
||||||
}
|
}
|
||||||
|
|
||||||
// {
|
// {
|
||||||
@@ -192,19 +192,19 @@ func newErrorEvent(code int, message string) ErrorEvent {
|
|||||||
// "activity_timeout" : 120
|
// "activity_timeout" : 120
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
type ConnectionEstablishedEventData struct {
|
type connectionEstablishedEventData struct {
|
||||||
SocketId string `json:"socket_id"`
|
SocketId string `json:"socket_id"`
|
||||||
ActivityTimeout int `json:"activity_timeout"`
|
ActivityTimeout int `json:"activity_timeout"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConnectionEstablishedEvent struct {
|
type connectionEstablishedEvent struct {
|
||||||
Event string `json:"event"`
|
Event string `json:"event"`
|
||||||
Data string `json:"data"`
|
Data string `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new connection established event using the specified socketId
|
// Create a new connection established event using the specified socketId
|
||||||
func newConnectionEstablishedEvent(socketId string) ConnectionEstablishedEvent {
|
func newConnectionEstablishedEvent(socketId string) connectionEstablishedEvent {
|
||||||
data := ConnectionEstablishedEventData{SocketId: socketId, ActivityTimeout: 120}
|
data := connectionEstablishedEventData{SocketId: socketId, ActivityTimeout: 120}
|
||||||
|
|
||||||
b, err := json.Marshal(data)
|
b, err := json.Marshal(data)
|
||||||
|
|
||||||
@@ -212,7 +212,7 @@ func newConnectionEstablishedEvent(socketId string) ConnectionEstablishedEvent {
|
|||||||
panic("events: Could not Marshal json ConnectionEstablishedEvent")
|
panic("events: Could not Marshal json ConnectionEstablishedEvent")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ConnectionEstablishedEvent{Event: "pusher:connection_established", Data: string(b)}
|
return connectionEstablishedEvent{Event: "pusher:connection_established", Data: string(b)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// {
|
// {
|
||||||
@@ -220,14 +220,14 @@ func newConnectionEstablishedEvent(socketId string) ConnectionEstablishedEvent {
|
|||||||
// "channel": "presence-example-channel",
|
// "channel": "presence-example-channel",
|
||||||
// "data": String
|
// "data": String
|
||||||
// }
|
// }
|
||||||
type MemberAddedEvent struct {
|
type memberAddedEvent struct {
|
||||||
Event string `json:"event"`
|
Event string `json:"event"`
|
||||||
Channel string `json:"channel"`
|
Channel string `json:"channel"`
|
||||||
Data string `json:"data"`
|
Data string `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMemberAddedEvent(channel, data string) MemberAddedEvent {
|
func newMemberAddedEvent(channel, data string) memberAddedEvent {
|
||||||
return MemberAddedEvent{Event: "pusher_internal:member_added", Channel: channel, Data: data}
|
return memberAddedEvent{Event: "pusher_internal:member_added", Channel: channel, Data: data}
|
||||||
}
|
}
|
||||||
|
|
||||||
// {
|
// {
|
||||||
@@ -235,13 +235,13 @@ func newMemberAddedEvent(channel, data string) MemberAddedEvent {
|
|||||||
// "channel": "presence-example-channel",
|
// "channel": "presence-example-channel",
|
||||||
// "data": String
|
// "data": String
|
||||||
// }
|
// }
|
||||||
type MemberRemovedEvent struct {
|
type memberRemovedEvent struct {
|
||||||
Event string `json:"event"`
|
Event string `json:"event"`
|
||||||
Channel string `json:"channel"`
|
Channel string `json:"channel"`
|
||||||
Data string `json:"data"`
|
Data string `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMemberRemovedEvent(channel string, s *Subscription) MemberRemovedEvent {
|
func newMemberRemovedEvent(channel string, s *subscription) memberRemovedEvent {
|
||||||
data, err := json.Marshal(struct {
|
data, err := json.Marshal(struct {
|
||||||
UserID string `json:"user_id"`
|
UserID string `json:"user_id"`
|
||||||
}{
|
}{
|
||||||
@@ -252,7 +252,7 @@ func newMemberRemovedEvent(channel string, s *Subscription) MemberRemovedEvent {
|
|||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return MemberRemovedEvent{Event: "pusher_internal:member_removed", Channel: channel, Data: string(data)}
|
return memberRemovedEvent{Event: "pusher_internal:member_removed", Channel: channel, Data: string(data)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// {
|
// {
|
||||||
@@ -260,19 +260,19 @@ func newMemberRemovedEvent(channel string, s *Subscription) MemberRemovedEvent {
|
|||||||
// "channel": "The channel",
|
// "channel": "The channel",
|
||||||
// "data": {}
|
// "data": {}
|
||||||
// }
|
// }
|
||||||
type RawEvent struct {
|
type rawEvent struct {
|
||||||
Event string `json:"event"`
|
Event string `json:"event"`
|
||||||
Channel string `json:"channel"`
|
Channel string `json:"channel"`
|
||||||
Data json.RawMessage `json:"data"`
|
Data json.RawMessage `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResponseEvent struct {
|
type responseEvent struct {
|
||||||
Event string `json:"event"`
|
Event string `json:"event"`
|
||||||
Channel string `json:"channel"`
|
Channel string `json:"channel"`
|
||||||
Data interface{} `json:"data"`
|
Data interface{} `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// The response event that is broadcasted to the client sockets
|
// The response event that is broadcasted to the client sockets
|
||||||
func newResponseEvent(name, channel string, data interface{}) ResponseEvent {
|
func newResponseEvent(name, channel string, data interface{}) responseEvent {
|
||||||
return ResponseEvent{Event: name, Channel: channel, Data: data}
|
return responseEvent{Event: name, Channel: channel, Data: data}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Conf holds the global configuration state
|
// Conf holds the global configuration state
|
||||||
var Conf ConfigFile
|
var Conf configFile
|
||||||
|
|
||||||
// Start Parse the configuration file and starts the ipe server
|
// Start Parse the configuration file and starts the ipe server
|
||||||
func Start(configfile string) error {
|
func Start(configfile string) error {
|
||||||
@@ -26,7 +26,7 @@ func Start(configfile string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Conf.Init()
|
Conf.Init()
|
||||||
router := NewRouter()
|
router := newRouter()
|
||||||
|
|
||||||
if err := http.ListenAndServe(Conf.Host, router); err != nil {
|
if err := http.ListenAndServe(Conf.Host, router); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
+1
-1
@@ -68,7 +68,7 @@ func postEvents(w http.ResponseWriter, r *http.Request) {
|
|||||||
for _, c := range input.Channels {
|
for _, c := range input.Channels {
|
||||||
channel := app.FindOrCreateChannelByChannelID(c)
|
channel := app.FindOrCreateChannelByChannelID(c)
|
||||||
|
|
||||||
app.Publish(channel, RawEvent{Event: input.Name, Channel: c, Data: input.Data}, input.SocketID)
|
app.Publish(channel, rawEvent{Event: input.Name, Channel: c, Data: input.Data}, input.SocketID)
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
// NewRouter is a function that returns a new configured Router
|
// NewRouter is a function that returns a new configured Router
|
||||||
// It add the necessary middlewares
|
// It add the necessary middlewares
|
||||||
func NewRouter() *mux.Router {
|
func newRouter() *mux.Router {
|
||||||
router := mux.NewRouter().StrictSlash(true)
|
router := mux.NewRouter().StrictSlash(true)
|
||||||
|
|
||||||
if Conf.Expvar {
|
if Conf.Expvar {
|
||||||
|
|||||||
+7
-9
@@ -9,7 +9,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// A route
|
// A route
|
||||||
type Route struct {
|
type route struct {
|
||||||
Name string
|
Name string
|
||||||
Method string
|
Method string
|
||||||
Pattern string
|
Pattern string
|
||||||
@@ -17,38 +17,36 @@ type Route struct {
|
|||||||
RequiresRestAuth bool
|
RequiresRestAuth bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Routes []Route
|
var routes = []route{
|
||||||
|
route{
|
||||||
var routes = Routes{
|
|
||||||
Route{
|
|
||||||
"PostEvents",
|
"PostEvents",
|
||||||
"POST",
|
"POST",
|
||||||
"/apps/{app_id}/events",
|
"/apps/{app_id}/events",
|
||||||
postEvents,
|
postEvents,
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
Route{
|
route{
|
||||||
"GetChannels",
|
"GetChannels",
|
||||||
"GET",
|
"GET",
|
||||||
"/apps/{app_id}/channels",
|
"/apps/{app_id}/channels",
|
||||||
getChannels,
|
getChannels,
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
Route{
|
route{
|
||||||
"GetChannel",
|
"GetChannel",
|
||||||
"GET",
|
"GET",
|
||||||
"/apps/{app_id}/channels/{channel_name}",
|
"/apps/{app_id}/channels/{channel_name}",
|
||||||
getChannel,
|
getChannel,
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
Route{
|
route{
|
||||||
"GetChannelUsers",
|
"GetChannelUsers",
|
||||||
"GET",
|
"GET",
|
||||||
"/apps/{app_id}/channels/{channel_name}/users",
|
"/apps/{app_id}/channels/{channel_name}/users",
|
||||||
getChannelUsers,
|
getChannelUsers,
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
Route{
|
route{
|
||||||
"Websocket",
|
"Websocket",
|
||||||
"GET",
|
"GET",
|
||||||
"/app/{key}",
|
"/app/{key}",
|
||||||
|
|||||||
+4
-4
@@ -5,13 +5,13 @@
|
|||||||
package ipe
|
package ipe
|
||||||
|
|
||||||
// A Channel Subscription
|
// A Channel Subscription
|
||||||
type Subscription struct {
|
type subscription struct {
|
||||||
Connection *Connection
|
Connection *connection
|
||||||
Id string
|
Id string
|
||||||
Data string
|
Data string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new Subscription
|
// Create a new Subscription
|
||||||
func newSubscription(conn *Connection, data string) *Subscription {
|
func newSubscription(conn *connection, data string) *subscription {
|
||||||
return &Subscription{Connection: conn, Data: data}
|
return &subscription{Connection: conn, Data: data}
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-25
@@ -33,12 +33,12 @@ import (
|
|||||||
//
|
//
|
||||||
// X-Pusher-Key: A Pusher app may have multiple tokens. The oldest active token will be used, identified by this key.
|
// X-Pusher-Key: A Pusher app may have multiple tokens. The oldest active token will be used, identified by this key.
|
||||||
// X-Pusher-Signature: A HMAC SHA256 hex digest formed by signing the POST payload (body) with the token’s secret.
|
// X-Pusher-Signature: A HMAC SHA256 hex digest formed by signing the POST payload (body) with the token’s secret.
|
||||||
type WebHook struct {
|
type webHook struct {
|
||||||
TimeMs int64 `json:"time_ms"`
|
TimeMs int64 `json:"time_ms"`
|
||||||
Events []HookEvent `json:"events"`
|
Events []hookEvent `json:"events"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type HookEvent struct {
|
type hookEvent struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Channel string `json:"channel"`
|
Channel string `json:"channel"`
|
||||||
Event string `json:"event,omitempty"`
|
Event string `json:"event,omitempty"`
|
||||||
@@ -47,36 +47,36 @@ type HookEvent struct {
|
|||||||
UserId string `json:"user_id,omitempty"`
|
UserId string `json:"user_id,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func newChannelOcuppiedHook(channel *Channel) HookEvent {
|
func newChannelOcuppiedHook(channel *channel) hookEvent {
|
||||||
return HookEvent{Name: "channel_occupied", Channel: channel.ChannelID}
|
return hookEvent{Name: "channel_occupied", Channel: channel.ChannelID}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newChannelVacatedHook(channel *Channel) HookEvent {
|
func newChannelVacatedHook(channel *channel) hookEvent {
|
||||||
return HookEvent{Name: "channel_vacated", Channel: channel.ChannelID}
|
return hookEvent{Name: "channel_vacated", Channel: channel.ChannelID}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMemberAddedHook(channel *Channel, s *Subscription) HookEvent {
|
func newMemberAddedHook(channel *channel, s *subscription) hookEvent {
|
||||||
return HookEvent{Name: "member_added", Channel: channel.ChannelID, UserId: s.Id}
|
return hookEvent{Name: "member_added", Channel: channel.ChannelID, UserId: s.Id}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMemberRemovedHook(channel *Channel, s *Subscription) HookEvent {
|
func newMemberRemovedHook(channel *channel, s *subscription) hookEvent {
|
||||||
return HookEvent{Name: "member_removed", Channel: channel.ChannelID, UserId: s.Id}
|
return hookEvent{Name: "member_removed", Channel: channel.ChannelID, UserId: s.Id}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newClientHook(channel *Channel, s *Subscription, event string, data interface{}) HookEvent {
|
func newClientHook(channel *channel, s *subscription, event string, data interface{}) hookEvent {
|
||||||
return HookEvent{Name: "client_event", Channel: channel.ChannelID, Event: event, Data: data, SocketID: s.Connection.SocketID}
|
return hookEvent{Name: "client_event", Channel: channel.ChannelID, Event: event, Data: data, SocketID: s.Connection.SocketID}
|
||||||
}
|
}
|
||||||
|
|
||||||
// channel_occupied
|
// channel_occupied
|
||||||
// { "name": "channel_occupied", "channel": "test_channel" }
|
// { "name": "channel_occupied", "channel": "test_channel" }
|
||||||
func (a *App) TriggerChannelOccupiedHook(c *Channel) {
|
func (a *app) TriggerChannelOccupiedHook(c *channel) {
|
||||||
event := newChannelOcuppiedHook(c)
|
event := newChannelOcuppiedHook(c)
|
||||||
triggerHook(event.Name, a, c, event)
|
triggerHook(event.Name, a, c, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
// channel_vacated
|
// channel_vacated
|
||||||
// { "name": "channel_vacated", "channel": "test_channel" }
|
// { "name": "channel_vacated", "channel": "test_channel" }
|
||||||
func (a *App) TriggerChannelVacatedHook(c *Channel) {
|
func (a *app) TriggerChannelVacatedHook(c *channel) {
|
||||||
event := newChannelVacatedHook(c)
|
event := newChannelVacatedHook(c)
|
||||||
triggerHook(event.Name, a, c, event)
|
triggerHook(event.Name, a, c, event)
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@ func (a *App) TriggerChannelVacatedHook(c *Channel) {
|
|||||||
// "socket_id": "socket_id of the sending socket",
|
// "socket_id": "socket_id of the sending socket",
|
||||||
// "user_id": "user_id associated with the sending socket" # Only for presence channels
|
// "user_id": "user_id associated with the sending socket" # Only for presence channels
|
||||||
// }
|
// }
|
||||||
func (a *App) TriggerClientEventHook(c *Channel, s *Subscription, client_event string, data interface{}) {
|
func (a *app) TriggerClientEventHook(c *channel, s *subscription, client_event string, data interface{}) {
|
||||||
event := newClientHook(c, s, client_event, data)
|
event := newClientHook(c, s, client_event, data)
|
||||||
|
|
||||||
if c.IsPresence() {
|
if c.IsPresence() {
|
||||||
@@ -104,7 +104,7 @@ func (a *App) TriggerClientEventHook(c *Channel, s *Subscription, client_event s
|
|||||||
// "channel": "presence-your_channel_name",
|
// "channel": "presence-your_channel_name",
|
||||||
// "user_id": "a_user_id"
|
// "user_id": "a_user_id"
|
||||||
// }
|
// }
|
||||||
func (a *App) TriggerMemberAddedHook(c *Channel, s *Subscription) {
|
func (a *app) TriggerMemberAddedHook(c *channel, s *subscription) {
|
||||||
event := newMemberAddedHook(c, s)
|
event := newMemberAddedHook(c, s)
|
||||||
triggerHook(event.Name, a, c, event)
|
triggerHook(event.Name, a, c, event)
|
||||||
}
|
}
|
||||||
@@ -114,21 +114,21 @@ func (a *App) TriggerMemberAddedHook(c *Channel, s *Subscription) {
|
|||||||
// "channel": "presence-your_channel_name",
|
// "channel": "presence-your_channel_name",
|
||||||
// "user_id": "a_user_id"
|
// "user_id": "a_user_id"
|
||||||
// }
|
// }
|
||||||
func (a *App) TriggerMemberRemovedHook(c *Channel, s *Subscription) {
|
func (a *app) TriggerMemberRemovedHook(c *channel, s *subscription) {
|
||||||
event := newMemberRemovedHook(c, s)
|
event := newMemberRemovedHook(c, s)
|
||||||
triggerHook(event.Name, a, c, event)
|
triggerHook(event.Name, a, c, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
func triggerHook(name string, app *App, c *Channel, event HookEvent) {
|
func triggerHook(name string, a *app, c *channel, event hookEvent) {
|
||||||
if !app.WebHooks {
|
if !a.WebHooks {
|
||||||
log.Infof("Webhooks are not enabled for app: %s", app.Name)
|
log.Infof("Webhooks are not enabled for app: %s", a.Name)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
log.Infof("Triggering %s event", name)
|
log.Infof("Triggering %s event", name)
|
||||||
|
|
||||||
hook := WebHook{TimeMs: time.Now().Unix()}
|
hook := webHook{TimeMs: time.Now().Unix()}
|
||||||
|
|
||||||
hook.Events = append(hook.Events, event)
|
hook.Events = append(hook.Events, event)
|
||||||
|
|
||||||
@@ -144,15 +144,15 @@ func triggerHook(name string, app *App, c *Channel, event HookEvent) {
|
|||||||
|
|
||||||
var req *http.Request
|
var req *http.Request
|
||||||
|
|
||||||
req, err = http.NewRequest("POST", app.URLWebHook, bytes.NewReader(js))
|
req, err = http.NewRequest("POST", a.URLWebHook, bytes.NewReader(js))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error creating request: %+v", err)
|
log.Errorf("Error creating request: %+v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
req.Header.Set("X-Pusher-Key", app.Key)
|
req.Header.Set("X-Pusher-Key", a.Key)
|
||||||
req.Header.Set("X-Pusher-Signature", utils.HashMAC(js, []byte(app.Secret)))
|
req.Header.Set("X-Pusher-Signature", utils.HashMAC(js, []byte(a.Secret)))
|
||||||
|
|
||||||
log.V(1).Infof("%+v", req.Header)
|
log.V(1).Infof("%+v", req.Header)
|
||||||
log.V(1).Infof("%+v", string(js))
|
log.V(1).Infof("%+v", string(js))
|
||||||
|
|||||||
+7
-7
@@ -26,7 +26,7 @@ var upgrader = websocket.Upgrader{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle open Subscriber.
|
// Handle open Subscriber.
|
||||||
func onOpen(conn *websocket.Conn, w http.ResponseWriter, r *http.Request, sessionID string, app *App) WebsocketError {
|
func onOpen(conn *websocket.Conn, w http.ResponseWriter, r *http.Request, sessionID string, app *app) websocketError {
|
||||||
params := r.URL.Query()
|
params := r.URL.Query()
|
||||||
p := params.Get("protocol")
|
p := params.Get("protocol")
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ func onOpen(conn *websocket.Conn, w http.ResponseWriter, r *http.Request, sessio
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle the close event
|
// Handle the close event
|
||||||
func onClose(sessionID string, app *App) {
|
func onClose(sessionID string, app *app) {
|
||||||
app.Disconnect(sessionID)
|
app.Disconnect(sessionID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@ func onClose(sessionID string, app *App) {
|
|||||||
//
|
//
|
||||||
// If there is an unrecoverable error then break the loop,
|
// If there is an unrecoverable error then break the loop,
|
||||||
// otherwise just keep going.
|
// otherwise just keep going.
|
||||||
func onMessage(conn *websocket.Conn, w http.ResponseWriter, r *http.Request, sessionID string, app *App) {
|
func onMessage(conn *websocket.Conn, w http.ResponseWriter, r *http.Request, sessionID string, app *app) {
|
||||||
var event struct {
|
var event struct {
|
||||||
Event string `json:"event"`
|
Event string `json:"event"`
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,7 @@ func onMessage(conn *websocket.Conn, w http.ResponseWriter, r *http.Request, ses
|
|||||||
emitWSError(newGenericReconnectImmediatelyError(), conn)
|
emitWSError(newGenericReconnectImmediatelyError(), conn)
|
||||||
}
|
}
|
||||||
case "pusher:subscribe":
|
case "pusher:subscribe":
|
||||||
subscribeEvent := SubscribeEvent{}
|
subscribeEvent := subscribeEvent{}
|
||||||
|
|
||||||
if err := json.Unmarshal(message, &subscribeEvent); err != nil {
|
if err := json.Unmarshal(message, &subscribeEvent); err != nil {
|
||||||
emitWSError(newGenericReconnectImmediatelyError(), conn)
|
emitWSError(newGenericReconnectImmediatelyError(), conn)
|
||||||
@@ -142,7 +142,7 @@ func onMessage(conn *websocket.Conn, w http.ResponseWriter, r *http.Request, ses
|
|||||||
emitWSError(newGenericReconnectImmediatelyError(), conn)
|
emitWSError(newGenericReconnectImmediatelyError(), conn)
|
||||||
}
|
}
|
||||||
case "pusher:unsubscribe":
|
case "pusher:unsubscribe":
|
||||||
unsubscribeEvent := UnsubscribeEvent{}
|
unsubscribeEvent := unsubscribeEvent{}
|
||||||
|
|
||||||
if err := json.Unmarshal(message, &unsubscribeEvent); err != nil {
|
if err := json.Unmarshal(message, &unsubscribeEvent); err != nil {
|
||||||
emitWSError(newGenericReconnectImmediatelyError(), conn)
|
emitWSError(newGenericReconnectImmediatelyError(), conn)
|
||||||
@@ -171,7 +171,7 @@ func onMessage(conn *websocket.Conn, w http.ResponseWriter, r *http.Request, ses
|
|||||||
emitWSError(newGenericError("To send client events, you must enable this feature in the Settings."), conn)
|
emitWSError(newGenericError("To send client events, you must enable this feature in the Settings."), conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientEvent := RawEvent{}
|
clientEvent := rawEvent{}
|
||||||
|
|
||||||
if err := json.Unmarshal(message, &clientEvent); err != nil {
|
if err := json.Unmarshal(message, &clientEvent); err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
@@ -237,7 +237,7 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Emit an Websocket ErrorEvent
|
// Emit an Websocket ErrorEvent
|
||||||
func emitWSError(err WebsocketError, conn *websocket.Conn) {
|
func emitWSError(err websocketError, conn *websocket.Conn) {
|
||||||
|
|
||||||
event := newErrorEvent(err.GetCode(), err.GetMsg())
|
event := newErrorEvent(err.GetCode(), err.GetMsg())
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user