|
@@ -0,0 +1,82 @@
|
|
|
+package channel
|
|
|
+
|
|
|
+import (
|
|
|
+ "errors"
|
|
|
+ "github.com/gorilla/websocket"
|
|
|
+ "message-pusher/common"
|
|
|
+ "message-pusher/model"
|
|
|
+ "sync"
|
|
|
+)
|
|
|
+
|
|
|
+var clientConnMap map[int]*websocket.Conn
|
|
|
+var clientConnMapMutex sync.Mutex
|
|
|
+
|
|
|
+func init() {
|
|
|
+ clientConnMapMutex.Lock()
|
|
|
+ clientConnMap = make(map[int]*websocket.Conn)
|
|
|
+ clientConnMapMutex.Unlock()
|
|
|
+}
|
|
|
+
|
|
|
+func SendMessageWithConn(message *Message, conn *websocket.Conn) error {
|
|
|
+ return conn.WriteJSON(message)
|
|
|
+}
|
|
|
+
|
|
|
+func LogoutClient(userId int) {
|
|
|
+ clientConnMapMutex.Lock()
|
|
|
+ delete(clientConnMap, userId)
|
|
|
+ clientConnMapMutex.Unlock()
|
|
|
+}
|
|
|
+
|
|
|
+func RegisterClient(userId int, conn *websocket.Conn) {
|
|
|
+ clientConnMapMutex.Lock()
|
|
|
+ oldConn, existed := clientConnMap[userId]
|
|
|
+ clientConnMapMutex.Unlock()
|
|
|
+ if existed {
|
|
|
+ byeMessage := &Message{
|
|
|
+ Title: common.SystemName,
|
|
|
+ Description: "其他客户端已连接服务器,本客户端已被挤下线!",
|
|
|
+ }
|
|
|
+ err := SendMessageWithConn(byeMessage, oldConn)
|
|
|
+ if err != nil {
|
|
|
+ common.SysError("error send message to client: " + err.Error())
|
|
|
+ }
|
|
|
+ err = oldConn.Close()
|
|
|
+ if err != nil {
|
|
|
+ common.SysError("error close WebSocket connection: " + err.Error())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ helloMessage := &Message{
|
|
|
+ Title: common.SystemName,
|
|
|
+ Description: "客户端连接成功!",
|
|
|
+ }
|
|
|
+ err := SendMessageWithConn(helloMessage, conn)
|
|
|
+ if err != nil {
|
|
|
+ common.SysError("error send message to client: " + err.Error())
|
|
|
+ return
|
|
|
+ } else {
|
|
|
+ clientConnMapMutex.Lock()
|
|
|
+ clientConnMap[userId] = conn
|
|
|
+ clientConnMapMutex.Unlock()
|
|
|
+ conn.SetCloseHandler(func(code int, text string) error {
|
|
|
+ LogoutClient(userId)
|
|
|
+ return nil
|
|
|
+ })
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func SendClientMessage(message *Message, user *model.User) error {
|
|
|
+ if user.ClientSecret == "" {
|
|
|
+ return errors.New("未配置 WebSocket 客户端消息推送方式")
|
|
|
+ }
|
|
|
+ clientConnMapMutex.Lock()
|
|
|
+ conn, existed := clientConnMap[user.Id]
|
|
|
+ clientConnMapMutex.Unlock()
|
|
|
+ if !existed {
|
|
|
+ return errors.New("客户端未连接")
|
|
|
+ }
|
|
|
+ err := SendMessageWithConn(message, conn)
|
|
|
+ if err != nil {
|
|
|
+ LogoutClient(user.Id)
|
|
|
+ }
|
|
|
+ return err
|
|
|
+}
|