melody icon indicating copy to clipboard operation
melody copied to clipboard

how get active sessions

Open imanborumand opened this issue 4 years ago • 3 comments

hi how i get active sessions for use in private chat?

thanks

imanborumand avatar Feb 05 '21 19:02 imanborumand

fork this repo and merge this change https://github.com/olahol/melody/pull/52

hah avatar Feb 11 '21 12:02 hah

fork this repo and merge this change #52

That's not a good way to manage all sessions if you copy all sessions to another map every time in a high concurrency service, it is very performance unfriendly.

lesismal avatar May 20 '21 03:05 lesismal

hi how i get active sessions for use in private chat?

thanks

if you just need to do some broadcast, use:

m.Broadcast
m.BroadcastFilter
m.BroadcastOthers
m.BroadcastMultiple
m.BroadcastBinary
m.BroadcastBinaryFilter
m.BroadcastBinaryOthers 

else if you need to do some more, you can manage all sessions at application layer, for example:

package main

import (
	"sync"

	"github.com/gin-gonic/gin"
	"github.com/olahol/melody"
)

type SessionMgr struct {
	mux      sync.RWMutex
	sessions map[interface{}]*melody.Session
}

func (mgr *SessionMgr) Get(id interface{}) (*melody.Session, bool) {
	mgr.mux.RLock()
	defer mgr.mux.RUnlock()
	sess, ok := mgr.sessions[id]
	return sess, ok
}

func (mgr *SessionMgr) Set(id interface{}, sess *melody.Session) {
	mgr.mux.Lock()
	defer mgr.mux.Unlock()
	mgr.sessions[id] = sess
}

func (mgr *SessionMgr) Delete(id interface{}) {
	mgr.mux.Lock()
	defer mgr.mux.Unlock()
	delete(mgr.sessions, id)
}

func (mgr *SessionMgr) ForEach(filter func(sess *melody.Session) bool, handler func(sess *melody.Session)) {
	mgr.mux.RLock()
	defer mgr.mux.RUnlock()
	for _, sess := range mgr.sessions {
		if filter(sess) {
			handler(sess)
		}
	}
}

var (
	sessionMgr = SessionMgr{
		sessions: map[interface{}]*melody.Session{},
	}
)

func main() {
	r := gin.Default()
	m := melody.New()

	m.HandleConnect(func(sess *melody.Session) {
		id := getIDFromSession(sess)
		sessionMgr.Set(id, sess)
	})

	m.HandleDisconnect(func(sess *melody.Session) {
		id := getIDFromSession(sess)
		sessionMgr.Delete(id)
	})

	r.GET("/ws", func(c *gin.Context) {
		m.HandleRequest(c.Writer, c.Request)
	})

	m.HandleMessage(func(s *melody.Session, msg []byte) {
		// ...
	})

	r.Run(":5000")
}

lesismal avatar May 20 '21 03:05 lesismal

I merged #52, but as @lesismal says it's not very performant, although the package probably needs a performance rewrite anyway.

olahol avatar Sep 14 '22 14:09 olahol