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
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|