代码拉取完成,页面将自动刷新
package network
import (
"errors"
"github.com/gorilla/websocket"
"gitee.com/aarlin/leaflet/log"
"net"
"sync"
"time"
)
type WebsocketConnSet map[*websocket.Conn]struct{}
type WSConn struct {
sync.Mutex
conn *websocket.Conn
writeChan chan []byte
maxMsgLen uint32
closeFlag bool
readTimeOut time.Duration
}
func newWSConn(conn *websocket.Conn, pendingWriteNum int, maxMsgLen uint32,readTimeOut time.Duration) *WSConn {
wsConn := new(WSConn)
wsConn.conn = conn
wsConn.writeChan = make(chan []byte, pendingWriteNum)
wsConn.maxMsgLen = maxMsgLen
wsConn.readTimeOut = readTimeOut
go func() {
for b := range wsConn.writeChan {
if b == nil {
break
}
err := conn.WriteMessage(websocket.BinaryMessage, b)
if err != nil {
break
}
}
conn.Close()
wsConn.Lock()
wsConn.closeFlag = true
wsConn.Unlock()
}()
return wsConn
}
func (wsConn *WSConn) doDestroy() {
wsConn.conn.UnderlyingConn().(*net.TCPConn).SetLinger(0)
wsConn.conn.Close()
if !wsConn.closeFlag {
close(wsConn.writeChan)
wsConn.closeFlag = true
}
}
func (wsConn *WSConn) Destroy() {
wsConn.Lock()
defer wsConn.Unlock()
wsConn.doDestroy()
}
func (wsConn *WSConn) Close() {
wsConn.Lock()
defer wsConn.Unlock()
if wsConn.closeFlag {
return
}
wsConn.doWrite(nil)
wsConn.closeFlag = true
}
func (wsConn *WSConn) doWrite(b []byte) {
if len(wsConn.writeChan) == cap(wsConn.writeChan) {
log.Debug("close conn: channel full")
wsConn.doDestroy()
return
}
wsConn.writeChan <- b
}
func (wsConn *WSConn) LocalAddr() net.Addr {
return wsConn.conn.LocalAddr()
}
func (wsConn *WSConn) RemoteAddr() net.Addr {
return wsConn.conn.RemoteAddr()
}
func (wsConn *WSConn) Read(p []byte) (n int, err error){
return 0,nil
}
func (wsConn *WSConn) Write(p []byte){
}
// goroutine not safe
func (wsConn *WSConn) ReadMsg() ([]byte, error) {
if wsConn.readTimeOut > 0 {
wsConn.conn.SetReadDeadline(time.Now().Add(wsConn.readTimeOut))
}
_, b, err := wsConn.conn.ReadMessage()
return b, err
}
// args must not be modified by the others goroutines
func (wsConn *WSConn) WriteMsg(args ...[]byte) error {
wsConn.Lock()
defer wsConn.Unlock()
if wsConn.closeFlag {
return nil
}
// get len
var msgLen uint32
for i := 0; i < len(args); i++ {
msgLen += uint32(len(args[i]))
}
// check len
if msgLen > wsConn.maxMsgLen {
return errors.New("message too long")
} else if msgLen < 1 {
return errors.New("message too short")
}
// don't copy
if len(args) == 1 {
wsConn.doWrite(args[0])
return nil
}
// merge the args
msg := make([]byte, msgLen)
l := 0
for i := 0; i < len(args); i++ {
copy(msg[l:], args[i])
l += len(args[i])
}
wsConn.doWrite(msg)
return nil
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。