1 Star 0 Fork 1

abigbug / gdot

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
client.go 4.79 KB
一键复制 编辑 原始数据 按行查看 历史
KuRay 提交于 2020-10-09 10:40 . 1、第一次提交
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
}
Go
1
https://gitee.com/abigbug/gdot.git
git@gitee.com:abigbug/gdot.git
abigbug
gdot
gdot
7424bbb5d2b3

搜索帮助