Triggering Presence channels events.
This commit is contained in:
@@ -102,6 +102,7 @@ func (a *App) Disconnect(socketID string) {
|
|||||||
defer a.Unlock()
|
defer a.Unlock()
|
||||||
|
|
||||||
_, exists := a.Subscribers[s.SocketID]
|
_, exists := a.Subscribers[s.SocketID]
|
||||||
|
|
||||||
if !exists {
|
if !exists {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -192,6 +193,6 @@ func (a *App) Unsubscribe(c *Channel, s *Subscriber) error {
|
|||||||
return c.Unsubscribe(a, s)
|
return c.Unsubscribe(a, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) Subscribe(c *Channel, s *Subscriber, data string) {
|
func (a *App) Subscribe(c *Channel, s *Subscriber, data string) error {
|
||||||
c.Subscribe(a, s, data)
|
return c.Subscribe(a, s, data)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
log "github.com/golang/glog"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
"github.com/dimiro1/ipe/utils"
|
"github.com/dimiro1/ipe/utils"
|
||||||
@@ -52,6 +53,7 @@ func RestAuthenticationHandler(h http.Handler) http.Handler {
|
|||||||
app, err := Conf.GetAppByAppID(appID)
|
app, err := Conf.GetAppByAppID(appID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
http.Error(w, "Not authorized", http.StatusUnauthorized)
|
http.Error(w, "Not authorized", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -68,6 +70,7 @@ func RestAuthenticationHandler(h http.Handler) http.Handler {
|
|||||||
if utils.HashMAC([]byte(toSign), []byte(app.Secret)) == signature {
|
if utils.HashMAC([]byte(toSign), []byte(app.Secret)) == signature {
|
||||||
h.ServeHTTP(w, r)
|
h.ServeHTTP(w, r)
|
||||||
} else {
|
} else {
|
||||||
|
log.Error("Not authorized")
|
||||||
http.Error(w, "Not authorized", http.StatusUnauthorized)
|
http.Error(w, "Not authorized", http.StatusUnauthorized)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -11,22 +11,12 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
log "github.com/golang/glog"
|
log "github.com/golang/glog"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This mutex is used to sync the generation of the new ID
|
|
||||||
var mutex = &sync.Mutex{}
|
|
||||||
|
|
||||||
// This variable store the current user id
|
|
||||||
// Every call to newID this variable is incremented
|
|
||||||
var currentID = 0
|
|
||||||
|
|
||||||
// A subscriber
|
// A subscriber
|
||||||
type Subscriber struct {
|
type Subscriber struct {
|
||||||
Id string
|
|
||||||
SocketID string
|
SocketID string
|
||||||
Socket *websocket.Conn
|
Socket *websocket.Conn
|
||||||
}
|
}
|
||||||
@@ -34,6 +24,7 @@ type Subscriber struct {
|
|||||||
// A Channel Subscription
|
// A Channel Subscription
|
||||||
type Subscription struct {
|
type Subscription struct {
|
||||||
Subscriber *Subscriber
|
Subscriber *Subscriber
|
||||||
|
Id string
|
||||||
Data string
|
Data string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,36 +79,69 @@ 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, data string) {
|
func (c *Channel) Subscribe(a *App, s *Subscriber, channelData string) error {
|
||||||
log.Infof("Subscribing %s to channel %s", s.SocketID, c.ChannelID)
|
log.Infof("Subscribing %s to channel %s", s.SocketID, c.ChannelID)
|
||||||
|
|
||||||
c.Lock()
|
c.Lock()
|
||||||
c.Subscriptions[s.SocketID] = NewSubscription(s, data)
|
defer c.Unlock()
|
||||||
c.Unlock()
|
|
||||||
|
subscription := NewSubscription(s, channelData)
|
||||||
|
c.Subscriptions[s.SocketID] = subscription
|
||||||
|
|
||||||
if c.IsPresence() {
|
if c.IsPresence() {
|
||||||
// Publish pusher_internal:member_added - Para todos
|
|
||||||
|
// User Info Data
|
||||||
|
var info struct {
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
UserInfo json.RawMessage `json:"user_info"`
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("%+v", channelData)
|
||||||
|
|
||||||
|
if err := json.Unmarshal([]byte(channelData), &info); err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
js, err := info.UserInfo.MarshalJSON()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the Subscription
|
||||||
|
subscription.Id = info.UserID
|
||||||
|
subscription.Data = string(js)
|
||||||
|
|
||||||
|
// Publish pusher_internal:member_added
|
||||||
|
c.PublishMemberAddedEvent(a, channelData, subscription)
|
||||||
|
|
||||||
// WebHook
|
// WebHook
|
||||||
a.TriggerMemberAddedHook(c, s)
|
a.TriggerMemberAddedHook(c, subscription)
|
||||||
|
|
||||||
// pusher_internal:subscription_succeeded
|
// pusher_internal:subscription_succeeded
|
||||||
data := make(map[string]SubscriptionSucceeedEventPresenceData, 1)
|
data := make(map[string]SubscriptionSucceeedEventPresenceData, 1)
|
||||||
data["presence"] = NewSubscriptionSucceedEventPresenceData(c)
|
data["presence"] = NewSubscriptionSucceedEventPresenceData(c)
|
||||||
|
|
||||||
js, err := json.Marshal(data)
|
js, err = json.Marshal(data)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.Publish(NewSubscriptionSucceededEvent(c.ChannelID, string(js))); err != nil {
|
s.Publish(NewSubscriptionSucceededEvent(c.ChannelID, string(js)))
|
||||||
log.Error(err)
|
} else {
|
||||||
}
|
s.Publish(NewSubscriptionSucceededEvent(c.ChannelID, "{}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebHook
|
// WebHook
|
||||||
if c.TotalSubscriptions() == 1 {
|
if c.TotalSubscriptions() == 1 {
|
||||||
a.TriggerChannelOccupiedHook(c)
|
a.TriggerChannelOccupiedHook(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsSubscribed check if the user is subscribed
|
// IsSubscribed check if the user is subscribed
|
||||||
@@ -134,7 +158,7 @@ func (c *Channel) Unsubscribe(a *App, s *Subscriber) error {
|
|||||||
c.Lock()
|
c.Lock()
|
||||||
defer c.Unlock()
|
defer c.Unlock()
|
||||||
|
|
||||||
_, exists := c.Subscriptions[s.SocketID]
|
subscription, exists := c.Subscriptions[s.SocketID]
|
||||||
|
|
||||||
if !exists {
|
if !exists {
|
||||||
return errors.New("Subscription not found")
|
return errors.New("Subscription not found")
|
||||||
@@ -144,8 +168,10 @@ func (c *Channel) Unsubscribe(a *App, s *Subscriber) error {
|
|||||||
|
|
||||||
if c.IsPresence() {
|
if c.IsPresence() {
|
||||||
// Publish pusher_internal:member_removed
|
// Publish pusher_internal:member_removed
|
||||||
|
c.PublishMemberRemovedEvent(a, subscription)
|
||||||
|
|
||||||
// Webhook
|
// Webhook
|
||||||
a.TriggerMemberRemovedHook(c, s)
|
a.TriggerMemberRemovedHook(c, subscription)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebHook
|
// WebHook
|
||||||
@@ -163,23 +189,33 @@ func NewChannel(channelID string) *Channel {
|
|||||||
return &Channel{ChannelID: channelID, CreatedAt: time.Now(), Subscriptions: make(map[string]*Subscription)}
|
return &Channel{ChannelID: channelID, CreatedAt: time.Now(), Subscriptions: make(map[string]*Subscription)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function generate a sequencial ID
|
|
||||||
func newID() (string, int) {
|
|
||||||
mutex.Lock()
|
|
||||||
defer mutex.Unlock()
|
|
||||||
|
|
||||||
currentID += 1
|
|
||||||
|
|
||||||
return strconv.Itoa(currentID), currentID
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new Subscriber
|
// Create a new Subscriber
|
||||||
func NewSubscriber(socketID string, s *websocket.Conn) *Subscriber {
|
func NewSubscriber(socketID string, s *websocket.Conn) *Subscriber {
|
||||||
id, _ := newID()
|
log.Infof("Creating a new Subscriber %+v", socketID)
|
||||||
|
|
||||||
log.Infof("Creating a new Subscriber %+v with id %s", socketID, id)
|
return &Subscriber{SocketID: socketID, Socket: s}
|
||||||
|
}
|
||||||
|
|
||||||
return &Subscriber{Id: id, SocketID: socketID, Socket: s}
|
// Publish a MemberAddedEvent to all subscriptions
|
||||||
|
func (c *Channel) PublishMemberAddedEvent(a *App, data string, subscription *Subscription) error {
|
||||||
|
for _, subs := range c.Subscriptions {
|
||||||
|
if subs != subscription {
|
||||||
|
subs.Subscriber.Publish(NewMemberAddedEvent(c.ChannelID, data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Publish a MemberRemovedEvent to all subscriptions
|
||||||
|
func (c *Channel) PublishMemberRemovedEvent(a *App, subscription *Subscription) error {
|
||||||
|
for _, subs := range c.Subscriptions {
|
||||||
|
if subs != subscription {
|
||||||
|
subs.Subscriber.Publish(NewMemberRemovedEvent(c.ChannelID, subscription))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publish messages to all Subscribers
|
// Publish messages to all Subscribers
|
||||||
@@ -200,11 +236,7 @@ func (c *Channel) Publish(a *App, event RawEvent, ignore string) error {
|
|||||||
|
|
||||||
for _, subs := range c.Subscriptions {
|
for _, subs := range c.Subscriptions {
|
||||||
if subs.Subscriber.SocketID != ignore {
|
if subs.Subscriber.SocketID != ignore {
|
||||||
js := NewResponseEvent(event.Event, event.Channel, v)
|
subs.Subscriber.Publish(NewResponseEvent(event.Event, event.Channel, v))
|
||||||
|
|
||||||
if err := subs.Subscriber.Publish(js); err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Webhook
|
// Webhook
|
||||||
if strings.HasPrefix(event.Event, "client-") {
|
if strings.HasPrefix(event.Event, "client-") {
|
||||||
@@ -217,11 +249,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{}) error {
|
func (s *Subscriber) Publish(m interface{}) {
|
||||||
if err := s.Socket.WriteJSON(m); err != nil {
|
go func() {
|
||||||
log.Errorf("Error sending message to subscriber %+v, %s", s, err)
|
if err := s.Socket.WriteJSON(m); err != nil {
|
||||||
return err
|
log.Errorf("Error sending message to subscriber %+v, %s", s, err)
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,11 @@
|
|||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "encoding/json"
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
log "github.com/golang/glog"
|
||||||
|
)
|
||||||
|
|
||||||
// {
|
// {
|
||||||
// "event": "pusher:subscribe",
|
// "event": "pusher:subscribe",
|
||||||
@@ -86,25 +90,29 @@ func NewSubscriptionSucceededEvent(channel, data string) SubscriptionSucceededEv
|
|||||||
// }
|
// }
|
||||||
// }"
|
// }"
|
||||||
type SubscriptionSucceeedEventPresenceData struct {
|
type SubscriptionSucceeedEventPresenceData struct {
|
||||||
Ids []string `json:"ids"`
|
Ids []string `json:"ids"`
|
||||||
Hash map[string]string `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]string, c.TotalSubscriptions())
|
hash := make(map[string]interface{}, c.TotalSubscriptions())
|
||||||
|
|
||||||
for _, s := range c.Subscriptions {
|
for _, s := range c.Subscriptions {
|
||||||
ids = append(ids, s.Subscriber.SocketID)
|
// Do you have any other idea?
|
||||||
hash[s.Subscriber.SocketID] = s.Data
|
var js interface{}
|
||||||
|
json.Unmarshal([]byte(s.Data), &js)
|
||||||
|
|
||||||
|
hash[s.Id] = js
|
||||||
|
ids = append(ids, s.Id)
|
||||||
}
|
}
|
||||||
|
|
||||||
event.Ids = ids
|
event.Ids = ids
|
||||||
event.Hash = hash
|
event.Hash = hash
|
||||||
event.count = c.TotalSubscriptions()
|
event.Count = c.TotalSubscriptions()
|
||||||
|
|
||||||
return event
|
return event
|
||||||
}
|
}
|
||||||
@@ -233,8 +241,18 @@ type MemberRemovedEvent struct {
|
|||||||
Data string `json:"data"`
|
Data string `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMemberRemovedEvent(channel, data string) MemberRemovedEvent {
|
func NewMemberRemovedEvent(channel string, s *Subscription) MemberRemovedEvent {
|
||||||
return MemberRemovedEvent{Event: "pusher_internal:member_removed", Channel: channel, Data: data}
|
data, err := json.Marshal(struct {
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
}{
|
||||||
|
UserID: s.Id,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return MemberRemovedEvent{Event: "pusher_internal:member_removed", Channel: channel, Data: string(data)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// {
|
// {
|
||||||
|
|||||||
@@ -157,7 +157,10 @@ func GetChannels(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||||
|
|
||||||
if err := json.NewEncoder(w).Encode(channels); err != nil {
|
js := make(map[string]interface{}, 1)
|
||||||
|
js["channels"] = channels
|
||||||
|
|
||||||
|
if err := json.NewEncoder(w).Encode(js); err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
@@ -257,8 +260,8 @@ func GetChannel(w http.ResponseWriter, r *http.Request) {
|
|||||||
// Example:
|
// Example:
|
||||||
// {
|
// {
|
||||||
// "users": [
|
// "users": [
|
||||||
// { "id": 1 },
|
// { "id": "1" },
|
||||||
// { "id": 2 }
|
// { "id": "2" }
|
||||||
// ]
|
// ]
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
@@ -298,7 +301,7 @@ func GetChannelUsers(w http.ResponseWriter, r *http.Request) {
|
|||||||
for _, s := range channel.Subscriptions {
|
for _, s := range channel.Subscriptions {
|
||||||
users = append(users, struct {
|
users = append(users, struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
}{s.Subscriber.Id})
|
}{s.Id})
|
||||||
}
|
}
|
||||||
|
|
||||||
result["users"] = users
|
result["users"] = users
|
||||||
|
|||||||
+6
-6
@@ -55,11 +55,11 @@ 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 *Subscriber) 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 *Subscriber) 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}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ func (a *App) TriggerClientEventHook(c *Channel, s *Subscription, client_event s
|
|||||||
event := NewClientHook(c, s, client_event, data)
|
event := NewClientHook(c, s, client_event, data)
|
||||||
|
|
||||||
if c.IsPresence() {
|
if c.IsPresence() {
|
||||||
event.UserId = s.Subscriber.Id
|
event.UserId = s.Id
|
||||||
}
|
}
|
||||||
|
|
||||||
triggerHook(event.Name, a, c, event)
|
triggerHook(event.Name, a, c, event)
|
||||||
@@ -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 *Subscriber) {
|
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,14 +114,14 @@ func (a *App) TriggerMemberAddedHook(c *Channel, s *Subscriber) {
|
|||||||
// "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 *Subscriber) {
|
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, app *App, c *Channel, event HookEvent) {
|
||||||
if !app.WebHooks {
|
if !app.WebHooks {
|
||||||
log.Infof("Checking webhooks enabled for app: %+v", app)
|
log.Infof("Checking webhooks enabled for app: %s", app.Name)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-4
@@ -131,7 +131,6 @@ func onMessage(conn *websocket.Conn, w http.ResponseWriter, r *http.Request, ses
|
|||||||
}
|
}
|
||||||
|
|
||||||
expectedAuthKey := fmt.Sprintf("%s:%s", app.Key, utils.HashMAC([]byte(strings.Join(toSign, ":")), []byte(app.Secret)))
|
expectedAuthKey := fmt.Sprintf("%s:%s", app.Key, utils.HashMAC([]byte(strings.Join(toSign, ":")), []byte(app.Secret)))
|
||||||
|
|
||||||
if subscribeEvent.Data.Auth != expectedAuthKey {
|
if subscribeEvent.Data.Auth != expectedAuthKey {
|
||||||
emitWSError(NewGenericError(fmt.Sprintf("Auth value for subscription to %s is invalid", channelName)), conn)
|
emitWSError(NewGenericError(fmt.Sprintf("Auth value for subscription to %s is invalid", channelName)), conn)
|
||||||
continue
|
continue
|
||||||
@@ -139,11 +138,10 @@ func onMessage(conn *websocket.Conn, w http.ResponseWriter, r *http.Request, ses
|
|||||||
}
|
}
|
||||||
|
|
||||||
channel := app.FindOrCreateChannelByChannelID(channelName)
|
channel := app.FindOrCreateChannelByChannelID(channelName)
|
||||||
app.Subscribe(channel, subscriber, subscribeEvent.Data.ChannelData)
|
log.Info(subscribeEvent.Data.ChannelData)
|
||||||
|
|
||||||
if err := conn.WriteJSON(NewSubscriptionSucceededEvent(channel.ChannelID, "{}")); err != nil {
|
if err := app.Subscribe(channel, subscriber, subscribeEvent.Data.ChannelData); err != nil {
|
||||||
emitWSError(NewGenericReconnectImmediatelyError(), conn)
|
emitWSError(NewGenericReconnectImmediatelyError(), conn)
|
||||||
break
|
|
||||||
}
|
}
|
||||||
case "pusher:unsubscribe":
|
case "pusher:unsubscribe":
|
||||||
unsubscribeEvent := UnsubscribeEvent{}
|
unsubscribeEvent := UnsubscribeEvent{}
|
||||||
|
|||||||
Reference in New Issue
Block a user