go-pattern-examples/gomore/27_messages/message.go

119 lines
2.4 KiB
Go
Raw Normal View History

2020-04-28 07:31:29 +03:00
package gomore
import (
"errors"
"time"
)
2020-04-28 12:24:15 +03:00
//Message for msg in Message bus
2020-04-28 07:31:29 +03:00
type Message struct {
2020-04-29 09:09:22 +03:00
//Type 类型[code :1,2,3,4]
Type int
Text string
From Session //消息来源
2020-04-28 07:31:29 +03:00
}
//User for user
type User struct {
ID uint64
Name string
}
//Session of user
type Session struct {
User User
Timestamp time.Time
}
//Subscription for user
2020-04-29 09:09:22 +03:00
//Subscription is a session
2020-04-28 07:31:29 +03:00
type Subscription struct {
2020-04-29 09:09:22 +03:00
Session
ch chan<- Message //发送队列
Inbox <-chan Message //接收消息的队列
2020-04-28 07:31:29 +03:00
}
//Publish a message to subscription queue
func (s *Subscription) Publish(msg Message) error {
if _, ok := <-s.ch; !ok {
return errors.New("Topic has been closed")
}
2020-04-28 12:24:15 +03:00
//用go channel 作为队列,接收消息
2020-04-28 07:31:29 +03:00
s.ch <- msg
return nil
}
//Topic that user is interested in
2020-04-29 09:09:22 +03:00
//Topic locate in MQ
2020-04-28 07:31:29 +03:00
type Topic struct {
2020-04-28 12:24:15 +03:00
Name string
2020-04-29 09:09:22 +03:00
Subscribers map[uint64]Session //user list
MessageHistory []Message //当前主题的消息历史,实际项目中可能需要限定大小并设置过期时间
subscription Subscription
2020-04-28 12:24:15 +03:00
}
2020-04-29 09:09:22 +03:00
//Queue hold all topics
type Queue struct {
Topics map[string]*Topic //topic ID<-----> topic Object
2020-04-28 17:48:25 +03:00
}
2020-04-28 12:24:15 +03:00
//String remove Subscription
func (t *Topic) String() string {
return t.Name
2020-04-28 07:31:29 +03:00
}
2020-04-29 09:09:22 +03:00
func (t *Topic) findSession(uid uint64) (Session, bool) {
// Get session or create one if it's the first
var Session session
if t.Subscribers == nil || len(t.Subscribers) == 0 {
return Session{}, false
}
if session, found := t.Subscribers[uid]; found {
return session, true
}
return Session{}, false
}
func (t *Topic) addSession(uid uint64) Session {
var Session session
2020-04-28 12:24:15 +03:00
// Get session or create one if it's the first
2020-04-29 09:09:22 +03:00
if session, found := t.findSession(uid); !found {
if t.Subscribers == ni {
t.Subscribers = make(map[uint64]Session)
}
session = Session{User{uid, "no name"}, time.Now()}
t.Subscribers[uid] = session
}
return session
}
//Subscribe a spec topic
func (t *Topic) Subscribe(uid uint64) (Subscription, error) {
2020-04-28 07:31:29 +03:00
2020-04-29 09:09:22 +03:00
session := t.addSession(uid)
2020-04-28 07:31:29 +03:00
2020-04-29 09:09:22 +03:00
// Create a subscription from copy
subscription := Subscription{session, t.subscription.ch, t.subscription.Inbox}
2020-04-28 07:31:29 +03:00
2020-04-29 09:09:22 +03:00
return subscription, nil
2020-04-28 07:31:29 +03:00
}
//Unsubscribe remove Subscription
2020-04-29 09:09:22 +03:00
func (t *Topic) Unsubscribe(s Subscription) error {
if t.findSession(s.User.ID) {
delete(t.Subscribers, s.User.ID)
}
2020-04-28 07:31:29 +03:00
return nil
}
2020-04-28 12:24:15 +03:00
//Delete topic
2020-04-28 07:31:29 +03:00
func (t *Topic) Delete() error {
2020-04-29 09:09:22 +03:00
t.Subscribers = nil
t.Name = ""
t.MessageHistory = nil
t.subscription = Subscription{}
2020-04-28 07:31:29 +03:00
return nil
}