Changed Type from Subsriber to Connection.

I think Connection is a better name.
This commit is contained in:
claudemiro
2015-01-15 20:13:42 -03:00
parent edf4b421bf
commit 7032e69ffb
5 changed files with 64 additions and 68 deletions
+23 -24
View File
@@ -28,14 +28,14 @@ type App struct {
URLWebHook string URLWebHook string
Channels map[string]*Channel `json:"-"` Channels map[string]*Channel `json:"-"`
Subscribers map[string]*Subscriber `json:"-"` Connections map[string]*Connection `json:"-"`
Stats *expvar.Map `json:"-"` Stats *expvar.Map `json:"-"`
} }
// Alloc memory for Subscribers and Channels // Alloc memory for Connections and Channels
func (a *App) Init() { func (a *App) Init() {
a.Subscribers = make(map[string]*Subscriber) 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))
} }
@@ -83,7 +83,7 @@ func (a *App) PublicChannels() []*Channel {
func (a *App) Disconnect(socketID string) { func (a *App) Disconnect(socketID string) {
log.Infof("Disconnecting socket %+v", socketID) log.Infof("Disconnecting socket %+v", socketID)
s, err := a.FindSubscriber(socketID) conn, err := a.FindConnection(socketID)
if err != nil { if err != nil {
log.Infof("Socket not found, %+v", err) log.Infof("Socket not found, %+v", err)
@@ -92,8 +92,8 @@ func (a *App) Disconnect(socketID string) {
// Unsubscribe from channels // Unsubscribe from channels
for _, c := range a.Channels { for _, c := range a.Channels {
if c.IsSubscribed(s) { if c.IsSubscribed(conn) {
c.Unsubscribe(a, s) c.Unsubscribe(a, conn)
} }
} }
@@ -101,38 +101,37 @@ func (a *App) Disconnect(socketID string) {
a.Lock() a.Lock()
defer a.Unlock() defer a.Unlock()
_, exists := a.Subscribers[s.SocketID] _, exists := a.Connections[conn.SocketID]
if !exists { if !exists {
return return
} }
delete(a.Subscribers, s.SocketID) delete(a.Connections, conn.SocketID)
a.Stats.Add("TotalSubscribers", -1) a.Stats.Add("TotalConnections", -1)
} }
// Connect a new Subscriber // Connect a new Subscriber
func (a *App) Connect(s *Subscriber) { func (a *App) Connect(conn *Connection) {
log.Infof("Adding a new Subscriber %s to app %s", s.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()
a.Subscribers[s.SocketID] = s a.Connections[conn.SocketID] = conn
a.Stats.Add("TotalSubscribers", 1) a.Stats.Add("TotalConnections", 1)
} }
// Find a Subscriber on this app // Find a Connection on this app
func (a *App) FindSubscriber(socketID string) (*Subscriber, error) { func (a *App) FindConnection(socketID string) (*Connection, error) {
conn, exists := a.Connections[socketID]
s, exists := a.Subscribers[socketID]
if exists { if exists {
return s, nil return conn, nil
} }
return nil, errors.New("Subscriber not found") return nil, errors.New("Connection not found")
} }
// Add a new Channel to this APP // Add a new Channel to this APP
@@ -141,6 +140,7 @@ func (a *App) AddChannel(c *Channel) {
a.Lock() a.Lock()
defer a.Unlock() defer a.Unlock()
a.Channels[c.ChannelID] = c a.Channels[c.ChannelID] = c
if c.IsPresence() { if c.IsPresence() {
@@ -173,7 +173,6 @@ 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 {
@@ -189,10 +188,10 @@ func (a *App) Publish(c *Channel, event RawEvent, ignore string) error {
return c.Publish(a, event, ignore) return c.Publish(a, event, ignore)
} }
func (a *App) Unsubscribe(c *Channel, s *Subscriber) error { func (a *App) Unsubscribe(c *Channel, conn *Connection) error {
return c.Unsubscribe(a, s) return c.Unsubscribe(a, conn)
} }
func (a *App) Subscribe(c *Channel, s *Subscriber, data string) error { func (a *App) Subscribe(c *Channel, conn *Connection, data string) error {
return c.Subscribe(a, s, data) return c.Subscribe(a, conn, data)
} }
+30 -33
View File
@@ -15,25 +15,20 @@ import (
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
) )
// A subscriber // An User Connection
type Subscriber struct { type Connection struct {
SocketID string SocketID string
Socket *websocket.Conn Socket *websocket.Conn
} }
// A Channel Subscription // A Channel Subscription
type Subscription struct { type Subscription struct {
Subscriber *Subscriber Connection *Connection
Id string Id string
Data string Data string
} }
// Create a new Subscription // A Channel
func NewSubscription(subscriber *Subscriber, data string) *Subscription {
return &Subscription{Subscriber: subscriber, Data: data}
}
// A channel
type Channel struct { type Channel struct {
sync.Mutex sync.Mutex
@@ -42,6 +37,11 @@ type Channel struct {
Subscriptions map[string]*Subscription Subscriptions map[string]*Subscription
} }
// Create a new Subscription
func NewSubscription(conn *Connection, data string) *Subscription {
return &Subscription{Connection: conn, Data: data}
}
// 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
@@ -84,17 +84,16 @@ 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, s *Subscriber, channelData string) error { func (c *Channel) Subscribe(a *App, conn *Connection, channelData string) error {
log.Infof("Subscribing %s to channel %s", s.SocketID, c.ChannelID) log.Infof("Subscribing %s to channel %s", conn.SocketID, c.ChannelID)
c.Lock() c.Lock()
defer c.Unlock() defer c.Unlock()
subscription := NewSubscription(s, channelData) subscription := NewSubscription(conn, channelData)
c.Subscriptions[s.SocketID] = subscription c.Subscriptions[conn.SocketID] = subscription
if c.IsPresence() { if c.IsPresence() {
// User Info Data // User Info Data
var info struct { var info struct {
UserID string `json:"user_id"` UserID string `json:"user_id"`
@@ -121,7 +120,6 @@ func (c *Channel) Subscribe(a *App, s *Subscriber, channelData string) error {
// Publish pusher_internal:member_added // Publish pusher_internal:member_added
c.PublishMemberAddedEvent(a, channelData, subscription) c.PublishMemberAddedEvent(a, channelData, subscription)
// WebHook // WebHook
a.TriggerMemberAddedHook(c, subscription) a.TriggerMemberAddedHook(c, subscription)
@@ -136,9 +134,9 @@ func (c *Channel) Subscribe(a *App, s *Subscriber, channelData string) error {
return err return err
} }
s.Publish(NewSubscriptionSucceededEvent(c.ChannelID, string(js))) conn.Publish(NewSubscriptionSucceededEvent(c.ChannelID, string(js)))
} else { } else {
s.Publish(NewSubscriptionSucceededEvent(c.ChannelID, "{}")) conn.Publish(NewSubscriptionSucceededEvent(c.ChannelID, "{}"))
} }
// WebHook // WebHook
@@ -150,31 +148,30 @@ func (c *Channel) Subscribe(a *App, s *Subscriber, channelData string) error {
} }
// IsSubscribed check if the user is subscribed // IsSubscribed check if the user is subscribed
func (c *Channel) IsSubscribed(s *Subscriber) bool { func (c *Channel) IsSubscribed(conn *Connection) bool {
_, exists := c.Subscriptions[s.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, s *Subscriber) error { func (c *Channel) Unsubscribe(a *App, conn *Connection) error {
log.Infof("Unsubscribing %s from channel %s", s.SocketID, c.ChannelID) log.Infof("Unsubscribing %s from channel %s", conn.SocketID, c.ChannelID)
c.Lock() c.Lock()
defer c.Unlock() defer c.Unlock()
subscription, exists := c.Subscriptions[s.SocketID] subscription, exists := c.Subscriptions[conn.SocketID]
if !exists { if !exists {
return errors.New("Subscription not found") return errors.New("Subscription not found")
} }
delete(c.Subscriptions, s.SocketID) delete(c.Subscriptions, conn.SocketID)
if c.IsPresence() { if c.IsPresence() {
// Publish pusher_internal:member_removed // Publish pusher_internal:member_removed
c.PublishMemberRemovedEvent(a, subscription) c.PublishMemberRemovedEvent(a, subscription)
// Webhook // Webhook
a.TriggerMemberRemovedHook(c, subscription) a.TriggerMemberRemovedHook(c, subscription)
} }
@@ -195,17 +192,17 @@ func NewChannel(channelID string) *Channel {
} }
// Create a new Subscriber // Create a new Subscriber
func NewSubscriber(socketID string, s *websocket.Conn) *Subscriber { 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 &Subscriber{SocketID: socketID, Socket: s} return &Connection{SocketID: socketID, Socket: s}
} }
// 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.Subscriber.Publish(NewMemberAddedEvent(c.ChannelID, data)) subs.Connection.Publish(NewMemberAddedEvent(c.ChannelID, data))
} }
} }
} }
@@ -214,7 +211,7 @@ func (c *Channel) PublishMemberAddedEvent(a *App, data string, subscription *Sub
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.Subscriber.Publish(NewMemberRemovedEvent(c.ChannelID, subscription)) subs.Connection.Publish(NewMemberRemovedEvent(c.ChannelID, subscription))
} }
} }
} }
@@ -236,8 +233,8 @@ func (c *Channel) Publish(a *App, event RawEvent, ignore string) error {
log.Infof("Publishing message %+v to channel %s", v, c.ChannelID) log.Infof("Publishing message %+v to channel %s", v, c.ChannelID)
for _, subs := range c.Subscriptions { for _, subs := range c.Subscriptions {
if subs.Subscriber.SocketID != ignore { if subs.Connection.SocketID != ignore {
subs.Subscriber.Publish(NewResponseEvent(event.Event, event.Channel, v)) subs.Connection.Publish(NewResponseEvent(event.Event, event.Channel, v))
} else { } else {
// Webhook // Webhook
if strings.HasPrefix(event.Event, "client-") { if strings.HasPrefix(event.Event, "client-") {
@@ -250,10 +247,10 @@ func (c *Channel) Publish(a *App, event RawEvent, ignore string) error {
} }
// Publish the message to websocket atached to this client // Publish the message to websocket atached to this client
func (s *Subscriber) Publish(m interface{}) { func (conn *Connection) Publish(m interface{}) {
go func() { go func() {
if err := s.Socket.WriteJSON(m); err != nil { if err := conn.Socket.WriteJSON(m); err != nil {
log.Errorf("Error sending message to subscriber %+v, %s", s, err) log.Errorf("Error publishing message to connection %+v, %s", conn, err)
} }
}() }()
} }
+1 -1
View File
@@ -255,7 +255,7 @@ func GetChannel(w http.ResponseWriter, r *http.Request) {
} }
} }
// Allowed only to presence-channels // Allowed only for presence-channels
// //
// Example: // Example:
// { // {
+1 -1
View File
@@ -64,7 +64,7 @@ func NewMemberRemovedHook(channel *Channel, s *Subscription) HookEvent {
} }
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.Subscriber.SocketID} return HookEvent{Name: "client_event", Channel: channel.ChannelID, Event: event, Data: data, SocketID: s.Connection.SocketID}
} }
// channel_occupied // channel_occupied
+9 -9
View File
@@ -52,11 +52,11 @@ func onOpen(conn *websocket.Conn, w http.ResponseWriter, r *http.Request, sessio
} }
// Create the new Subscriber // Create the new Subscriber
subscriber := NewSubscriber(sessionID, conn) connection := NewConnection(sessionID, conn)
app.Connect(subscriber) app.Connect(connection)
// Everything went fine. Huhu. // Everything went fine. Huhu.
if err := conn.WriteJSON(NewConnectionEstablishedEvent(subscriber.SocketID)); err != nil { if err := conn.WriteJSON(NewConnectionEstablishedEvent(connection.SocketID)); err != nil {
return NewGenericReconnectImmediatelyError() return NewGenericReconnectImmediatelyError()
} }
@@ -111,7 +111,7 @@ func onMessage(conn *websocket.Conn, w http.ResponseWriter, r *http.Request, ses
break break
} }
subscriber, err := app.FindSubscriber(sessionID) connection, err := app.FindConnection(sessionID)
if err != nil { if err != nil {
emitWSError(NewGenericReconnectImmediatelyError(), conn) emitWSError(NewGenericReconnectImmediatelyError(), conn)
@@ -124,7 +124,7 @@ func onMessage(conn *websocket.Conn, w http.ResponseWriter, r *http.Request, ses
isPrivate := strings.HasPrefix(channelName, "private-") isPrivate := strings.HasPrefix(channelName, "private-")
if isPresence || isPrivate { if isPresence || isPrivate {
toSign := []string{subscriber.SocketID, channelName} toSign := []string{connection.SocketID, channelName}
if isPresence { if isPresence {
toSign = append(toSign, subscribeEvent.Data.ChannelData) toSign = append(toSign, subscribeEvent.Data.ChannelData)
@@ -140,7 +140,7 @@ func onMessage(conn *websocket.Conn, w http.ResponseWriter, r *http.Request, ses
channel := app.FindOrCreateChannelByChannelID(channelName) channel := app.FindOrCreateChannelByChannelID(channelName)
log.Info(subscribeEvent.Data.ChannelData) log.Info(subscribeEvent.Data.ChannelData)
if err := app.Subscribe(channel, subscriber, subscribeEvent.Data.ChannelData); err != nil { if err := app.Subscribe(channel, connection, subscribeEvent.Data.ChannelData); err != nil {
emitWSError(NewGenericReconnectImmediatelyError(), conn) emitWSError(NewGenericReconnectImmediatelyError(), conn)
} }
case "pusher:unsubscribe": case "pusher:unsubscribe":
@@ -150,10 +150,10 @@ func onMessage(conn *websocket.Conn, w http.ResponseWriter, r *http.Request, ses
emitWSError(NewGenericReconnectImmediatelyError(), conn) emitWSError(NewGenericReconnectImmediatelyError(), conn)
} }
subscriber, err := app.FindSubscriber(sessionID) connection, err := app.FindConnection(sessionID)
if err != nil { if err != nil {
emitWSError(NewGenericError(fmt.Sprintf("Could not find a subscriber with the id %s", sessionID)), conn) emitWSError(NewGenericError(fmt.Sprintf("Could not find a connection with the id %s", sessionID)), conn)
} }
channel, err := app.FindChannelByChannelID(unsubscribeEvent.Data.Channel) channel, err := app.FindChannelByChannelID(unsubscribeEvent.Data.Channel)
@@ -162,7 +162,7 @@ func onMessage(conn *websocket.Conn, w http.ResponseWriter, r *http.Request, ses
emitWSError(NewGenericError(fmt.Sprintf("Could not find a channel with the id %s", unsubscribeEvent.Data.Channel)), conn) emitWSError(NewGenericError(fmt.Sprintf("Could not find a channel with the id %s", unsubscribeEvent.Data.Channel)), conn)
} }
if err := app.Unsubscribe(channel, subscriber); err != nil { if err := app.Unsubscribe(channel, connection); err != nil {
emitWSError(NewGenericReconnectImmediatelyError(), conn) emitWSError(NewGenericReconnectImmediatelyError(), conn)
break break
} }