Files
CoreApp/util/ws/websocket.go
2025-08-11 11:54:58 +08:00

90 lines
1.5 KiB
Go

package ws
import (
"context"
"github.com/gorilla/websocket"
"log"
)
type Packet struct {
isBinary bool
data []byte
}
func Text(buf []byte) *Packet {
return &Packet{
isBinary: false,
data: buf,
}
}
func Binary(buf []byte) *Packet {
return &Packet{
isBinary: true,
data: buf,
}
}
type Conn struct {
WriteChan chan *Packet
ReadChan chan []byte
Context context.Context
cancel context.CancelFunc
conn *websocket.Conn
close bool
}
func Wrap(conn *websocket.Conn) *Conn {
ctx, cancel := context.WithCancel(context.Background())
return &Conn{
WriteChan: make(chan *Packet),
ReadChan: make(chan []byte),
conn: conn,
Context: ctx,
cancel: cancel,
close: false,
}
}
func (conn *Conn) ReadLoop() {
for !conn.close {
_, message, err := conn.conn.ReadMessage()
if err != nil {
if !websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseAbnormalClosure) {
log.Println("websocket read error:", err)
}
conn.Close()
break
}
conn.ReadChan <- message
}
}
func (conn *Conn) WriteLoop() {
for {
select {
case message := <-conn.WriteChan:
typ := websocket.TextMessage
if message.isBinary {
typ = websocket.BinaryMessage
}
err := conn.conn.WriteMessage(typ, message.data)
if err != nil {
break
}
case <-conn.Context.Done():
return
}
}
}
func (conn *Conn) Close() error {
conn.cancel()
conn.close = true
return conn.conn.Close()
}
func (conn *Conn) IsClosed() bool {
return conn.close
}