新增:广播消息;

优化:订阅服务消息发送使用读锁

git-svn-id: svn://47.119.165.148/zhub@76 e63fbceb-bcc3-4977-ac22-735b83d8d0f4
This commit is contained in:
lxy
2021-01-21 11:05:49 +00:00
parent 03a7118598
commit 3c66a41de2
4 changed files with 66 additions and 39 deletions

View File

@@ -50,7 +50,7 @@ func Create(addr string, groupid string) (*Client, error) {
timerReceive: make(chan []string, 100), timerReceive: make(chan []string, 100),
} }
conn.Write([]byte("groupid " + groupid + "\r\n")) client.send("groupid " + groupid)
client.init() client.init()
return &client, err return &client, err
} }
@@ -64,15 +64,15 @@ func (c *Client) reconn() (err error) {
continue continue
} else if err == nil { } else if err == nil {
c.conn = conn c.conn = conn
conn.Write([]byte("groupid " + c.groupid + "\r\n")) c.send("groupid " + c.groupid)
go c.receive() go c.receive()
// 重新订阅 // 重新订阅
for topic, _ := range c.subFun { for topic, _ := range c.subFun {
c.subscribes(topic) c.Subscribe(topic, nil)
} }
for topic, _ := range c.timerFun { for topic, _ := range c.timerFun {
c.timer(topic) c.Timer(topic, nil)
} }
break break
} }
@@ -100,16 +100,23 @@ func (c *Client) init() {
} }
fun() fun()
} }
} }
}() }()
go c.receive() go c.receive()
} }
/*
// subscribe topic
---
subscribe x y z
---
*/
func (c *Client) Subscribe(topic string, fun func(v string)) { func (c *Client) Subscribe(topic string, fun func(v string)) {
c.send("subscribe " + topic)
if fun != nil {
c.subFun[topic] = fun c.subFun[topic] = fun
c.subscribes(topic) }
} }
/* /*
@@ -135,13 +142,15 @@ $24
--- ---
*/ */
func (c *Client) Publish(topic string, message string) error { func (c *Client) Publish(topic string, message string) error {
c.send("publish", topic, message) return c.send("publish", topic, message)
return nil }
func (c *Client) Broadcast(topic string, message string) error {
return c.send("broadcast", topic, message)
} }
func (c *Client) Daly(topic string, message string, daly int) error { func (c *Client) Daly(topic string, message string, daly int) error {
c.send("daly", topic, message, strconv.Itoa(daly)) return c.send("daly", topic, message, strconv.Itoa(daly))
return nil
} }
/*func (c *Client) Timer(topic string, expr string, fun func()) { /*func (c *Client) Timer(topic string, expr string, fun func()) {
@@ -149,16 +158,9 @@ func (c *Client) Daly(topic string, message string, daly int) error {
c.send("timer", topic, expr, "x") c.send("timer", topic, expr, "x")
}*/ }*/
func (c *Client) Timer(topic string, fun func()) { func (c *Client) Timer(topic string, fun func()) {
if fun != nil {
c.timerFun[topic] = fun c.timerFun[topic] = fun
c.send("timer", topic)
} }
func (c *Client) TimerSingle(topic string, expr string, fun func()) {
c.timerFun[topic] = fun
c.send("timer", topic, expr, "a")
}
// todo: save client timers info
func (c *Client) timer(topic string) {
c.send("timer", topic) c.send("timer", topic)
} }
@@ -171,13 +173,7 @@ func (c *Client) Close() {
c.conn.Close() c.conn.Close()
} }
/* /*func (c *Client) subscribes(topics ...string) error {
// subscribe topic
---
subscribe x y z
---
*/
func (c *Client) subscribes(topics ...string) error {
if len(topics) == 0 { if len(topics) == 0 {
return nil return nil
} }
@@ -188,7 +184,7 @@ func (c *Client) subscribes(topics ...string) error {
} }
c.send(messages) c.send(messages)
return nil return nil
} }*/
/* /*
send socket message : send socket message :

View File

@@ -2,6 +2,7 @@ package main
import ( import (
"log" "log"
"strconv"
"testing" "testing"
"time" "time"
"zhub/cli" "zhub/cli"
@@ -40,14 +41,22 @@ func TestCli(t *testing.T) {
} }
func TestTimer(t *testing.T) { func TestTimer(t *testing.T) {
go func() {
client, _ := cli.Create(addr, "topic-2")
client.Subscribe("ax", func(v string) {
log.Println("topic-1-ax: " + v)
})
}()
go func() { go func() {
client, _ := cli.Create(addr, "topic-1") client, _ := cli.Create(addr, "topic-1")
client.Timer("a", func() {
log.Println("client-1 收到 a 的定时消息") client.Subscribe("ax", func(v string) {
log.Println("topic-2-ax: " + v)
}) })
}() }()
go func() { /*go func() {
client, _ := cli.Create(addr, "topic-2") client, _ := cli.Create(addr, "topic-2")
client.Timer("a", func() { client.Timer("a", func() {
log.Println("client-2 收到 a 的定时消息") log.Println("client-2 收到 a 的定时消息")
@@ -69,7 +78,7 @@ func TestTimer(t *testing.T) {
client.Timer("VIP-EXP-EXPIRE", func() { client.Timer("VIP-EXP-EXPIRE", func() {
log.Println("client-2 收到 VIP-EXP-EXPIRE 的定时消息") log.Println("client-2 收到 VIP-EXP-EXPIRE 的定时消息")
}) })
}() }()*/
time.Sleep(time.Hour * 3) time.Sleep(time.Hour * 3)
} }
@@ -88,8 +97,9 @@ func TestPublish(t *testing.T) {
if err != nil { if err != nil {
log.Println(err) log.Println(err)
} }
for i := 0; i < 30_0000; i++ {
client.Publish("ax", "a") client.Publish("ax", strconv.Itoa(i))
}
time.Sleep(time.Second) time.Sleep(time.Second)
} }

View File

@@ -67,6 +67,8 @@ func msgAccept(v Message) {
} else { } else {
zsub.publish(rcmd[1], rcmd[2]) zsub.publish(rcmd[1], rcmd[2])
} }
case "broadcast":
zsub.broadcast(rcmd[1], rcmd[2])
case "daly": case "daly":
daly(rcmd, c) daly(rcmd, c)
case "timer": case "timer":

View File

@@ -17,7 +17,7 @@ var (
) )
type ZSub struct { type ZSub struct {
sync.Mutex sync.RWMutex
topics map[string]*ZTopic topics map[string]*ZTopic
timers map[string]*ZTimer timers map[string]*ZTimer
} }
@@ -99,9 +99,9 @@ accept topic message
1、send message to topic's chan 1、send message to topic's chan
2、feedback send success to sender, and sending message to topic's subscripts 2、feedback send success to sender, and sending message to topic's subscripts
*/ */
func (s *ZSub) publish(topic string, msg string) { func (s *ZSub) publish(topic, msg string) {
s.Lock() s.RLock()
defer s.Unlock() defer s.RUnlock()
ztopic := s.topics[topic] //ZTopic ztopic := s.topics[topic] //ZTopic
if ztopic == nil { if ztopic == nil {
return return
@@ -110,6 +110,25 @@ func (s *ZSub) publish(topic string, msg string) {
ztopic.mcount++ ztopic.mcount++
} }
/*
send broadcast message
*/
func (s *ZSub) broadcast(topic, msg string) {
s.RLock()
defer s.RUnlock()
ztopic := s.topics[topic] //ZTopic
if ztopic == nil {
return
}
for _, group := range ztopic.groups {
for _, conn := range group.conns {
conn.send("message", topic, msg)
}
}
}
func (s *ZSub) close(c *ZConn) { func (s *ZSub) close(c *ZConn) {
// sub // sub
for _, topic := range c.topics { for _, topic := range c.topics {