vRp.CD2g_test/server/gateway/endpoint.go

79 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package gateway
import (
"github.com/kercylan98/minotaur/server"
"github.com/kercylan98/minotaur/server/client"
"github.com/kercylan98/minotaur/utils/super"
"time"
)
// NewEndpoint 创建网关端点
func NewEndpoint(name, address string, options ...EndpointOption) *Endpoint {
endpoint := &Endpoint{
client: client.NewWebsocket(address),
name: name,
address: address,
}
for _, option := range options {
option(endpoint)
}
if endpoint.evaluator == nil {
endpoint.evaluator = func(costUnixNano float64) float64 {
return 1 / (1 + 1.5*time.Duration(costUnixNano).Seconds())
}
}
endpoint.client.RegWebsocketConnectionClosedEvent(endpoint.onConnectionClosed)
endpoint.client.RegWebsocketConnectionReceivePacketEvent(endpoint.onConnectionReceivePacket)
return endpoint
}
// Endpoint 网关端点
type Endpoint struct {
client *client.Websocket // 端点客户端
name string // 端点名称
address string // 端点地址
state float64 // 端点健康值0为不可用越高越优
offline bool // 离线
evaluator func(costUnixNano float64) float64 // 端点健康值评估函数
}
// Offline 离线
func (slf *Endpoint) Offline() {
slf.offline = true
}
// Connect 连接端点
func (slf *Endpoint) Connect() {
for {
cur := time.Now().UnixNano()
if err := slf.client.Run(); err == nil {
slf.state = slf.evaluator(float64(time.Now().UnixNano() - cur))
break
}
time.Sleep(100 * time.Millisecond)
}
}
// Write 写入数据
func (slf *Endpoint) Write(packet server.Packet) {
slf.client.Write(packet)
}
// onConnectionClosed 与端点连接断开事件
func (slf *Endpoint) onConnectionClosed(conn *client.Websocket, err any) {
if !slf.offline {
go slf.Connect()
}
}
// onConnectionReceivePacket 接收到来自端点的数据包事件
func (slf *Endpoint) onConnectionReceivePacket(conn *client.Websocket, packet server.Packet) {
var gp server.GP
if err := super.UnmarshalJSON(packet.Data[:len(packet.Data)-1], &gp); err != nil {
panic(err)
}
cur := time.Now().UnixNano()
slf.state = slf.evaluator(float64(cur - gp.T))
conn.GetData(gp.C).(*server.Conn).Write(server.NewWSPacket(gp.WT, gp.D))
}