func (ss *SessionStore) Create(conn interface{}, sid string) *Session { var s Session s.sid = sid switch c := conn.(type) { case *websocket.Conn: s.proto = WEBSOCK s.ws = c case http.ResponseWriter: s.proto = LPOLL s.wrt = c case *ClusterNode: s.proto = RPC s.rpcnode = c default: s.proto = NONE } if s.proto != NONE { s.subs = make(map[string]*Subscription) s.send = make(chan []byte, 64) // buffered s.stop = make(chan []byte, 1) // Buffered by 1 just to make it non-blocking s.detach = make(chan string, 64) // buffered } s.lastTouched = time.Now() if s.sid == "" { s.sid = store.GetUidString() } ss.rw.Lock() ss.sessCache[s.sid] = &s if s.proto == LPOLL { // Only LP sessions need to be sorted by last active s.lpTracker = ss.lru.PushFront(&s) // Remove expired sessions expire := s.lastTouched.Add(-ss.lifeTime) for elem := ss.lru.Back(); elem != nil; elem = ss.lru.Back() { sess := elem.Value.(*Session) if sess.lastTouched.Before(expire) { ss.lru.Remove(elem) delete(ss.sessCache, sess.sid) globals.cluster.sessionGone(sess) } else { break // don't need to traverse further } } } ss.rw.Unlock() return &s }
// Generate random string as a name of the group topic func genTopicName() string { return "grp" + store.GetUidString() }