You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
3.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* Created by GoLand.
* User: link1st
* Date: 2019-07-25
* Time: 16:24
*/
package websocket
import (
"fmt"
"github.com/gorilla/websocket"
"runtime/debug"
)
const (
// 用户连接超时时间
heartbeatExpirationTime = 6 * 60
)
// 用户登录
type login struct {
AppId uint32
UserId string
Client *Client
}
// 读取客户端数据
func (l *login) GetKey() (key string) {
key = GetUserKey(l.AppId, l.UserId)
return
}
// 用户连接
type Client struct {
Addr string // 客户端地址
Socket *websocket.Conn // 用户连接
Send chan []byte // 待发送的数据
AppId uint32 // 登录的平台Id app/web/ios
UserId string // 用户Id用户登录以后才有
FirstTime uint64 // 首次连接事件
HeartbeatTime uint64 // 用户上次心跳时间
LoginTime uint64 // 登录时间 登录以后才有
}
// 初始化
func NewClient(addr string, socket *websocket.Conn, firstTime uint64) (client *Client) {
client = &Client{
Addr: addr,
Socket: socket,
Send: make(chan []byte, 100),
FirstTime: firstTime,
HeartbeatTime: firstTime,
}
return
}
// 读取客户端数据
func (c *Client) GetKey() (key string) {
key = GetUserKey(c.AppId, c.UserId)
return
}
// 读取客户端数据
func (c *Client) read() {
defer func() {
if r := recover(); r != nil {
fmt.Println("write stop", string(debug.Stack()), r)
}
}()
defer func() {
fmt.Println("读取客户端数据 关闭send", c)
close(c.Send)
}()
for {
_, message, err := c.Socket.ReadMessage()
if err != nil {
fmt.Println("读取客户端数据 错误", c.Addr, err)
return
}
// 处理程序
fmt.Println("读取客户端数据 处理:", string(message))
ProcessData(c, message)
}
}
// 向客户端写数据
func (c *Client) write() {
defer func() {
if r := recover(); r != nil {
fmt.Println("write stop", string(debug.Stack()), r)
}
}()
defer func() {
clientManager.Unregister <- c
c.Socket.Close()
fmt.Println("Client发送数据 defer", c)
}()
for {
select {
case message, ok := <-c.Send:
if !ok {
// 发送数据错误 关闭连接
fmt.Println("Client发送数据 关闭连接", c.Addr, "ok", ok)
return
}
c.Socket.WriteMessage(websocket.TextMessage, message)
}
}
}
// 读取客户端数据
func (c *Client) SendMsg(msg []byte) {
if c == nil {
return
}
defer func() {
if r := recover(); r != nil {
fmt.Println("SendMsg stop:", r, string(debug.Stack()))
}
}()
c.Send <- msg
}
// 读取客户端数据
func (c *Client) close() {
close(c.Send)
}
// 用户登录
func (c *Client) Login(appId uint32, userId string, loginTime uint64) {
c.AppId = appId
c.UserId = userId
c.LoginTime = loginTime
// 登录成功=心跳一次
c.Heartbeat(loginTime)
}
// 用户心跳
func (c *Client) Heartbeat(currentTime uint64) {
c.HeartbeatTime = currentTime
return
}
// 心跳超时
func (c *Client) IsHeartbeatTimeout(currentTime uint64) (timeout bool) {
if c.HeartbeatTime+heartbeatExpirationTime <= currentTime {
timeout = true
}
return
}
// 是否登录了
func (c *Client) IsLogin() (isLogin bool) {
// 用户登录了
if c.UserId != "" {
isLogin = true
return
}
return
}