本次我们依然和使用Swoole开发一样,在application/services中新建一个push目录,然后将发送消息的方法通过观察者模式推送给用户。
首先,建立一个PushObServer的接口文件
package push
type PushObServer interface {
update() bool
}
然后我们需要新建一个方法来继承实现这个接口:
package push
import (
"encoding/json"
"github.com/astaxie/beego/logs"
"github.com/gorilla/websocket"
"go_chat/common"
)
type PushToAllMessage struct {
Status int
Fds []int
Msg string
Data common.MessageContent
Index int
Result common.ReturnData
}
func (p *PushToAllMessage) update() bool {
if p.Msg != "" {
p.Result.Msg = p.Msg
p.Result.Status=0
}else{
p.Result.Data = p.Data
}
jsonData, _ := json.Marshal(p.Result)
if len(p.Fds) == 0 {
logs.Error("没有需要被推送的用户!")
return false
}
for _, index := range p.Fds {
conn := common.Client[index]
conn.WriteMessage(websocket.TextMessage, jsonData)
}
return true
}
在这个方法中,我们可以完成所有状态的Push工作。
然后我们需要写一个services/push/PushEventGenerator类,用于接收所有的ObServer事件。
package push
type PushEventGenerator struct {
Events []PushObServer
}
func(p *PushEventGenerator) Add(server PushObServer){
p.Events=append(p.Events,server)
}
func(p *PushEventGenerator) Update(){
for _,event := range(p.Events){
event.update();
}
}
之后,在LoginService类中继承PushEventGenerator,以便可以直接通过LoginService来添加通知事件。
type LoginService struct {
services.CommonService
common.CommonFunction
push.PushEventGenerator
Index int
}
最后我们回到MessageController中,在用户订阅的时候发送两个消息,一个是告诉当前用户自己的订阅状态,一个是告诉所有用户有新用户进入了房间
case "login":
loginService := services.LoginService{
Index: m.Index,
}
messageContent:=common.MessageContent{
FirstTopic: umsg.FirstTopic,
SecondTopic: umsg.SecondTopic,
MsgType: 0,
MsgContent: fmt.Sprintf("UserId为%v进入了房间",umsg.UserId),
UserId: umsg.UserId,
}
//给自己推送一个注册成功的信息
PushToSelf:=new(push.PushToAllMessage)
PushToSelf.Status=0
PushToSelf.Msg="注册成功!"
PushToSelf.Fds=[]int{m.Index}
loginService.Add(PushToSelf)
//给所有人推送 xxx进来了的信息
fds:=new(user.UserService).GetFdByGroup(umsg.FirstTopic,umsg.SecondTopic)
fds=append(fds,m.Index)
fmt.Println("fds===================",fds)
PushToAllObj:=new(push.PushToAllMessage)
PushToAllObj.Status=0;
PushToAllObj.Data=messageContent
PushToAllObj.Fds=fds
loginService.Add(PushToAllObj)
result := loginService.Register(umsg)
fmt.Println(result)
break
订阅通知发送完成。
网友评论