代码拉取完成,页面将自动刷新
package gdnet
import (
"fmt"
"reflect"
"strings"
"time"
"gitee.com/abigbug/gdot/gdconf"
log "gitee.com/abigbug/gdot/gdlog"
"gitee.com/abigbug/gdot/gdproto"
"github.com/name5566/leaf/network"
)
// NewClient NewClient
func NewClient(p network.Processor, netAddr string) *Client {
return &Client{
netAddr: netAddr,
Processor: p,
}
}
// Client Client
type Client struct {
netAddr string
ctr *connector
a *agent
funClose func()
Processor network.Processor
OnConnected func()
OnClose func()
}
// NetAddr NetAddr
func (its *Client) NetAddr() string {
addr := its.Addr()
if split := strings.Split(addr, ":"); len(split) > 2 {
addr = fmt.Sprintf("%s://%s:%s", split[0], its.netAddr, split[2])
}
return addr
}
// Addr Addr
func (its *Client) Addr() string {
if nil != its.ctr {
if its.ctr.tcpAddr != "" {
split := strings.Split(its.ctr.tcpAddr, "//")
if len(split) > 1 {
return split[1]
}
return split[0]
}
if its.ctr.wsAddr != "" {
return its.ctr.wsAddr
}
}
return ""
}
// Send Send
func (its *Client) Send(id int32, msg interface{}) {
if nil != its.a {
its.a.Send(id, msg)
}
}
// Close Close
func (its *Client) Close() {
if its.funClose != nil {
its.funClose()
}
}
// Connect Connect
func (its *Client) Connect(url string, autoReconnect bool) error {
if nil != its.ctr {
return fmt.Errorf("client already connected")
}
ctr := &connector{
c: its,
autoReconnect: autoReconnect,
}
if split := strings.Split(url, "//"); len(split) > 1 {
if str := split[0]; strings.EqualFold(str, "tcp:") {
ctr.tcpAddr = split[1]
} else if strings.EqualFold(str, "ws:") {
ctr.wsAddr = url
} else {
return fmt.Errorf("invalid url %q", url)
}
} else {
ctr.tcpAddr = split[0]
}
its.ctr = ctr
its.ctr.Run()
return nil
}
type connector struct {
c *Client
wsAddr string
tcpAddr string
autoReconnect bool
}
func (its *connector) Run() {
var wsClient *network.WSClient
if its.wsAddr != "" {
wsClient = new(network.WSClient)
wsClient.Addr = its.wsAddr
wsClient.ConnNum = 1
wsClient.ConnectInterval = 3 * time.Second
wsClient.HandshakeTimeout = 10 * time.Second
wsClient.PendingWriteNum = gdconf.PendingWriteNum
wsClient.MaxMsgLen = gdconf.MaxMsgLen
wsClient.AutoReconnect = its.autoReconnect
wsClient.NewAgent = func(conn *network.WSConn) network.Agent {
a := &agent{conn: conn, c: its.c}
if its.c.a = a; its.c.OnConnected != nil {
its.c.OnConnected()
}
return a
}
}
var tcpClient *network.TCPClient
if its.tcpAddr != "" {
tcpClient = new(network.TCPClient)
tcpClient.Addr = its.tcpAddr
tcpClient.ConnNum = 1
tcpClient.PendingWriteNum = gdconf.PendingWriteNum
tcpClient.LenMsgLen = gdconf.LenMsgLen
tcpClient.MaxMsgLen = gdconf.MaxMsgLen
tcpClient.LittleEndian = gdconf.LittleEndian
tcpClient.AutoReconnect = its.autoReconnect
tcpClient.NewAgent = func(conn *network.TCPConn) network.Agent {
a := &agent{conn: conn, c: its.c}
if its.c.a = a; its.c.OnConnected != nil {
its.c.OnConnected()
}
return a
}
}
if wsClient != nil {
wsClient.Start()
}
if tcpClient != nil {
tcpClient.Start()
}
its.c.funClose = func() {
if wsClient != nil {
wsClient.Close()
}
if tcpClient != nil {
tcpClient.Close()
}
}
}
type agent struct {
conn network.Conn
c *Client
userData interface{}
}
func (a *agent) SendBytes(bytes [][]byte) {
if bytes == nil {
log.Error("bytes must not be nil")
return
}
if err := a.conn.WriteMsg(bytes...); nil != err {
log.Error("write message error: %v", err)
}
}
func (a *agent) Send(id int32, msg interface{}) {
if msg == nil {
log.Error("msg must not be nil")
return
}
if data := gdproto.NewMsg(id, msg); data != nil {
a.writeMsg(data)
}
}
func (a *agent) Run() {
for {
data, err := a.conn.ReadMsg()
if err != nil {
log.Debug("read message: %v", err)
break
}
if a.c.Processor != nil {
msg, err := a.c.Processor.Unmarshal(data)
if err != nil {
log.Debug("unmarshal message error: %v", err)
break
}
err = a.c.Processor.Route(msg, a)
if err != nil {
log.Debug("route message error: %v", err)
break
}
}
}
}
func (a *agent) OnClose() {
if a.c.OnClose != nil {
a.c.OnClose()
}
}
func (a *agent) writeMsg(msg interface{}) {
if a.c.Processor != nil {
data, err := a.c.Processor.Marshal(msg)
if err != nil {
log.Error("marshal message %v error: %v", reflect.TypeOf(msg), err)
return
}
err = a.conn.WriteMsg(data...)
if err != nil {
log.Error("write message %v error: %v", reflect.TypeOf(msg), err)
}
}
}
func (a *agent) Close() {
a.conn.Close()
}
func (a *agent) Destroy() {
a.conn.Destroy()
}
func (a *agent) UserData() interface{} {
return a.userData
}
func (a *agent) SetUserData(data interface{}) {
a.userData = data
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。