112 lines
2.8 KiB
Go
112 lines
2.8 KiB
Go
// Package ws -----------------------------
|
||
// @file : client.go
|
||
// @author : JJXu
|
||
// @contact : wavingbear@163.com
|
||
// @time : 2022/10/21 18:18:05
|
||
// -------------------------------------------
|
||
package ws
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"github.com/gorilla/websocket"
|
||
uuid "github.com/satori/go.uuid"
|
||
"go.uber.org/zap"
|
||
"log"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
var (
|
||
// 注册事件最大等待时间
|
||
limitRegisterWaitTime = time.Second * 6
|
||
limitReadTime = time.Second * 5
|
||
)
|
||
|
||
// NewClient 创建客户端实例
|
||
//
|
||
// param userId 用户id
|
||
// param uid 用户uuid
|
||
// param conn 客户端websocket连接对象
|
||
// return *Client
|
||
func NewClient(userId int64, uid string, conn *websocket.Conn, room *ChatRoom) *Client {
|
||
uidobj, _ := uuid.NewV4()
|
||
var v = &Client{
|
||
Room: room,
|
||
UserId: userId,
|
||
Uuid: uid,
|
||
ClientId: strings.Replace(uidobj.String(), "-", "", -1),
|
||
Conn: conn,
|
||
Send: make(chan []byte, 500),
|
||
}
|
||
return v
|
||
}
|
||
|
||
type Client struct {
|
||
Room *ChatRoom `json:"-" `
|
||
UserId int64 `json:"userId" ` //用户id
|
||
Uuid string `json:"uuid"` //画家uid
|
||
ClientId string `json:"clientId"` //为用户不同设备分配不同的客户端ID
|
||
Conn *websocket.Conn `json:"-"`
|
||
Send chan []byte
|
||
SessionId string `json:"sessionId"` //会话ID,同一个用户多客户端登录,会话ID相同
|
||
Waiter bool `json:"waiter"` //是否是客服
|
||
}
|
||
|
||
func (c *Client) Reading(ctx context.Context, handleFunc ...func(sourceData []byte, cli *Client)) {
|
||
defer func() {
|
||
c.Room.UnRegister <- c
|
||
ctx.Done()
|
||
return
|
||
}()
|
||
//c.Conn.SetReadLimit(maxMessageSize)
|
||
c.Conn.SetReadDeadline(time.Now().Add(pongWait))
|
||
//接收到ping命令后,更新读取时间
|
||
c.Conn.SetPongHandler(func(string) error {
|
||
c.Conn.SetReadDeadline(time.Now().Add(pongWait))
|
||
return nil
|
||
})
|
||
for {
|
||
msgType, byteData, err := c.Conn.ReadMessage()
|
||
if msgType == -1 {
|
||
return
|
||
}
|
||
if err != nil {
|
||
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
|
||
log.Println("ws连接已关闭", zap.Error(err))
|
||
}
|
||
break
|
||
}
|
||
if handleFunc != nil {
|
||
handleFunc[0](byteData, c)
|
||
} else {
|
||
HandleMessage(byteData, c)
|
||
}
|
||
}
|
||
}
|
||
func (c *Client) WriteWait() {
|
||
ticker := time.NewTicker(pingPeriod)
|
||
defer func() {
|
||
ticker.Stop()
|
||
c.Conn.Close()
|
||
}()
|
||
|
||
for {
|
||
select {
|
||
case msg, ok := <-c.Send:
|
||
fmt.Printf("发送消息:%+v\n", string(msg))
|
||
c.Conn.WriteMessage(websocket.TextMessage, msg)
|
||
fmt.Println("发送消息结束")
|
||
if !ok {
|
||
// 聊天室关闭了管道
|
||
c.Conn.WriteControl(websocket.CloseMessage, []byte{}, time.Now().Add(writeWait))
|
||
return
|
||
}
|
||
case <-ticker.C:
|
||
if err := c.Conn.WriteControl(websocket.PingMessage, nil, time.Now().Add(pongWait)); err != nil {
|
||
return
|
||
}
|
||
}
|
||
}
|
||
}
|