1 Star 0 Fork 0

dream_hat/dreamgo

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
requestsocket.go 6.55 KB
一键复制 编辑 原始数据 按行查看 历史
dream_hat 提交于 2023-12-20 11:22 +08:00 . update requestsocket.go.
package dream
import (
"bytes"
"encoding/binary"
"encoding/json"
"gitee.com/dream_hat/dreamgo/hd"
"net"
"strings"
"sync"
"time"
"unsafe"
)
func NewSocketPool(c string) IPool {
p := NewPool(func(c interface{}) interface{} {
var ssc string = ""
switch v := c.(type) {
case string:
ssc = string(v)
break
}
addrs := strings.Split(ssc, ",")
v := &sSocket{
headertemp: make([]byte, 7),
addr: addrs[0],
auth: addrs[1],
requestTimeout: 10,
xym: false,
}
return v
}, c, 0xffffffff)
return p
}
/*
ISocket 无状态连接
注:同步的
*/
type ISocket interface {
SendPackage(xy XY, pack []byte) error
ReadPackage(rxy ...XY) (XY, []byte, error)
Request(xy XY, pack []byte, rxy ...XY) (XY, []byte, error)
JSONSendPackage(xy XY, json map[string]interface{}) error
JSONReadPackage(rxy ...XY) (XY, map[string]interface{}, error)
JSONRequest(xy XY, json map[string]interface{}, rxy ...XY) (XY, map[string]interface{}, error)
}
type sSocket struct {
con net.Conn
lock *sync.Mutex
requestTimeout uint32
addr string
auth string
headertemp []byte
xym bool
key string
}
func (p *sSocket) gethdlen() int {
if p.xym {
return 2
} else {
return 137
}
}
func (p *sSocket) JSONSendPackage(xy XY, _json map[string]interface{}) error {
res, _ := json.Marshal(&_json)
return p.SendPackage(xy, res)
}
func (p *sSocket) JSONReadPackage(rxy ...XY) (xy XY, _json map[string]interface{}, err error) {
var by []byte
xy, by, err = p.ReadPackage(rxy...)
if err != nil {
return xy, nil, err
}
_json = make(map[string]interface{})
json.Unmarshal(by, &_json)
return xy, _json, err
}
func (p *sSocket) JSONRequest(xy XY, _json map[string]interface{}, rxy ...XY) (XY, map[string]interface{}, error) {
err := p.JSONSendPackage(xy, _json)
if err != nil {
return 0, nil, err
}
return p.JSONReadPackage(rxy...)
}
func (p *sSocket) SendPackage(xy XY, pack []byte) error {
doconnected := false
if p.con == nil {
p.connect()
doconnected = true
}
if p.con == nil {
return hd.E_BACK_CONNECT_ERROR
}
buf := allocPackWithInstall(true, xy, pack, p.gethdlen())
err := loopSend_2019_12_26(p.con, buf, p.requestTimeout)
if err != nil {
Logi(LOG_KERL, "socket send_2019_12_26 fail ", err)
p.con.Close()
p.con = nil
if doconnected {
freePack(buf)
return hd.E_BACK_SEND_ERROR
}
p.connect()
if p.con == nil {
freePack(buf)
return hd.E_BACK_CONNECT_ERROR
}
err := loopSend(p.con, buf, p.requestTimeout)
if err != nil {
Logi(LOG_KERL, "socket resend fail ", err)
freePack(buf)
p.con.Close()
p.con = nil
return hd.E_BACK_SEND_ERROR
}
}
freePack(buf)
return nil
}
func (p *sSocket) ReadPackage(rxy ...XY) (XY, []byte, error) {
if p.con == nil {
return 0, nil, hd.E_BACK_RECV_STATE_ERROR
}
tlen, err := recvPackageHeader(p.con, p.gethdlen(), p.requestTimeout, p.headertemp)
if err != nil {
Logi(LOG_KERL, "socket recv len fail ", err)
p.con.Close()
p.con = nil
return 0, nil, hd.E_BACK_RECV_ERROR
}
var xy XY = 0
if true {
if tlen < uint32(unsafe.Sizeof(xy)) {
Logi(LOG_KERL, "socket recved len < xy ")
p.con.Close()
p.con = nil
return 0, nil, hd.E_BACK_RECV_DATA_ERROR
}
}
var pack []byte = nil
if tlen > 0 {
pack = allocPack(tlen)
var err error
if isValidHenlen(p.gethdlen()) {
err = loopRecv(p.con, pack, p.requestTimeout)
} else {
var read int
read, err = tryRecv(p.con, pack, p.requestTimeout)
pack = pack[0:read]
}
if err != nil {
Logi(LOG_KERL, "socket recv ", tlen, " data fail ", err)
freePack(pack)
p.con.Close()
p.con = nil
return 0, nil, hd.E_BACK_RECV_DATA_ERROR
}
}
if true {
if tlen < uint32(unsafe.Sizeof(xy)) {
Logi(LOG_KERL, "socket recved len < xy ")
if pack != nil {
freePack(pack)
}
p.con.Close()
p.con = nil
return 0, nil, hd.E_BACK_RECV_DATA_ERROR
}
io := bytes.NewBuffer(pack)
binary.Read(io, binary.LittleEndian, &xy)
}
if len(rxy) > 0 {
if xy != rxy[0] {
p.con.Close()
p.con = nil
Logi(LOG_KERL, "socket need XY:", int(rxy[0]), ",but recved XY:", int(xy))
return xy, pack[int(unsafe.Sizeof(xy)):], hd.E_BACK_RECV_DATA_ERROR
}
}
return xy, pack[int(unsafe.Sizeof(xy)):], nil
}
func (p *sSocket) Request(xy XY, pack []byte, rxy ...XY) (XY, []byte, error) {
err := p.SendPackage(xy, pack)
if err != nil {
return 0, nil, err
}
return p.ReadPackage(rxy...)
}
func (p *sSocket) connect() {
Assert(p.con == nil, "socket connect not nil")
d := &net.Dialer{Timeout: time.Duration(p.requestTimeout) * time.Second}
c, err := d.Dial("tcp", p.addr)
if err != nil {
Logi(LOG_KERL, " socket connect ", p.addr, " fail ", err)
return
}
if p.xym {
} else {
j := NewJSON()
j["type"] = 0
j["id"] = 1
j["sign"] = ""
b, _ := json.Marshal(j)
pk := allocPackWithInstall(true, 30001, b, p.gethdlen())
var err = loopSend(c, pk, autosettings.wtimeouts)
if err != nil {
c.Close()
Logi(LOG_KERL, " socket auth ", p.addr, " sendfail ", err)
return
}
err = nil
var xy XY = 0
var pack []byte = nil
dlen, err := recvPackageHeader(c, p.gethdlen(), autosettings.rtimeouts, p.headertemp)
if err != nil {
c.Close()
Logi(LOG_KERL, " socket auth ", p.addr, " recvlenfail ", err)
return
}
if true {
if dlen < uint32(unsafe.Sizeof(xy)) {
c.Close()
Logi(LOG_KERL, " socket auth ", p.addr, " XY limit ")
return
}
}
if dlen > 0 {
pack = allocPack(dlen)
err = loopRecv(c, pack, autosettings.rtimeouts)
if err != nil {
c.Close()
Logi(LOG_KERL, " socket auth ", p.addr, " recvfail ", err)
return
}
}
if true {
if dlen < uint32(unsafe.Sizeof(xy)) {
c.Close()
Logi(LOG_KERL, " socket auth ", p.addr, " XY limit ")
return
}
io := bytes.NewBuffer(pack)
binary.Read(io, binary.LittleEndian, &xy)
}
dpack := pack[int(unsafe.Sizeof(xy)):]
var sid int64
var errori int64
if err != nil {
c.Close()
Logi(LOG_KERL, " socket auth ", p.addr, " recv fail:", err)
return
}
if xy != 30002 || dpack == nil || len(dpack) == 0 {
c.Close()
Logi(LOG_KERL, " socket auth ", p.addr, " Data err")
return
} else {
jr := NewJSON()
err = json.Unmarshal(dpack, &jr)
if err != nil {
c.Close()
Logi(LOG_KERL, " socket auth ", p.addr, " Json err")
return
} else {
jrd := JSONRead{
JSONT: jr,
}
sid = jrd.Num("id")
errori = jrd.Num("error")
if sid == 0 || errori != 0 {
c.Close()
Logi(LOG_KERL, " socket auth ", p.addr, " ret serverid err")
return
}
}
}
}
p.con = c
return
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/dream_hat/dreamgo.git
git@gitee.com:dream_hat/dreamgo.git
dream_hat
dreamgo
dreamgo
v1.1.2

搜索帮助