Ai
1 Star 0 Fork 1

啥大师/golang simple gather

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
server.go 3.51 KB
一键复制 编辑 原始数据 按行查看 历史
你çfrog 提交于 2023-04-28 23:02 +08:00 . perf 优化websocket
package gsws
import (
"gitee.com/Sxiaobai/gs/gstool"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"net/http"
"sync"
"time"
)
type Config struct {
Host string
Port string
Uri string //路由
ReadBufferSize int //IO读缓冲区
WriteBufferSize int //IO写缓冲区
CheckOrigin bool //是否检查跨域 true:不允许跨域,false:允许跨域
MaxLiveTime int64 //连接最大生存时间 心跳要小于这个值
MaxWriteWaitTime time.Duration //推送消息最大等待时间
MaxReadWaitTime time.Duration //读取消息最大的等待时间
MaxMessageSize int64 //消息最大byte
MaxClient int //最大的客户端数
}
// Server 服务总配置
type Server struct {
getClientIdFunc func() string //获取client Id回调
connCloseFunc func(string) //连接关闭回调
newConnFunc func(conn *WsConn, queryParams map[string]any) //新连接回调
ginH *gin.Engine
upGraderH *websocket.Upgrader
config Config //配置
currentClient int //当前的连接数
startTime int64 //启动时间 用于生成连接ID
cliConnMap map[string]*WsConn //所有客户端的连接
syncLock sync.RWMutex
}
// Start 启动
func (h *Server) Start() error {
h.ginH = gin.Default()
h.ginH.GET(h.config.Uri, h.connect)
h.upGraderH = &websocket.Upgrader{
ReadBufferSize: h.config.ReadBufferSize,
WriteBufferSize: h.config.WriteBufferSize,
}
h.startTime = time.Now().Unix()
h.cliConnMap = make(map[string]*WsConn)
//是否允许跨域
if !h.config.CheckOrigin {
h.upGraderH.CheckOrigin = func(r *http.Request) bool {
return true
}
}
return h.ginH.Run(h.config.Host + `:` + h.config.Port)
}
// SetConfig 设置配置
func (h *Server) SetConfig(conf Config) {
h.config = conf
}
// Connect 连接 升级为websocket
func (h *Server) connect(c *gin.Context) {
queryParams := h.getQueryParams(c)
//升级为websocket
conn, err := h.upGraderH.Upgrade(c.Writer, c.Request, nil)
if err != nil {
gstool.FmtPrintlnLog(`建立连接错误 %s`, err.Error())
return
}
if h.currentClient > h.config.MaxClient {
gstool.FmtPrintlnLog(`当前连接数已达上限`)
return
}
//当前连接数+1
h.currentClient++
//构造客户端连接
conn.SetReadLimit(h.config.MaxMessageSize) //设置消息最大字节
cliConn := WsConn{
conn: conn,
readChan: make(chan string, 1000),
writeChan: make(chan string, 1000),
mutex: sync.Mutex{},
isClosed: false,
closeChan: make(chan byte),
clientId: h.getClientIdFunc(),
serverHandle: h,
lastHeartTime: time.Now().Unix(),
}
h.addCliConn(&cliConn)
//新连接回调
h.newConnFunc(&cliConn, queryParams)
// 处理器,发送定时信息,避免意外关闭
go cliConn.doBusinessLoop()
// 读协程
go cliConn.wsReadLoop()
// 写协程
go cliConn.wsWriteLoop()
}
// 获取请求的参数
func (h *Server) getQueryParams(c *gin.Context) map[string]any {
query := c.Request.URL.Query()
var queryMap = make(map[string]any, len(query))
for k := range query {
queryMap[k] = c.Query(k)
}
return queryMap
}
// 增加一个连接
func (h *Server) addCliConn(cliConn *WsConn) {
h.syncLock.Lock()
h.cliConnMap[cliConn.clientId] = cliConn
h.syncLock.Unlock()
}
// 关闭连接
func (h *Server) removeCliConn(cliConn *WsConn) {
h.syncLock.Lock()
delete(h.cliConnMap, cliConn.clientId)
h.currentClient--
h.connCloseFunc(cliConn.clientId)
h.syncLock.Unlock()
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/Sxiaobai/gs.git
git@gitee.com:Sxiaobai/gs.git
Sxiaobai
gs
golang simple gather
v1.9.9

搜索帮助