vRp.CD2g_test/server/gateway/endpoint.go

103 lines
2.9 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/alphadose/haxmap"
"github.com/kercylan98/minotaur/server"
"github.com/kercylan98/minotaur/server/client"
"time"
)
// NewEndpoint 创建网关端点
func NewEndpoint(gateway *Gateway, name string, client *client.Client, options ...EndpointOption) *Endpoint {
endpoint := &Endpoint{
gateway: gateway,
client: client,
name: name,
address: client.GetServerAddr(),
connections: haxmap.New[string, *server.Conn](),
}
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.RegConnectionClosedEvent(endpoint.onConnectionClosed)
endpoint.client.RegConnectionReceivePacketEvent(endpoint.onConnectionReceivePacket)
return endpoint
}
// Endpoint 网关端点
type Endpoint struct {
gateway *Gateway
client *client.Client // 端点客户端
name string // 端点名称
address string // 端点地址
state float64 // 端点健康值0为不可用越高越优
offline bool // 离线
evaluator func(costUnixNano float64) float64 // 端点健康值评估函数
connections *haxmap.Map[string, *server.Conn] // 连接列表
}
// Link 连接端点
func (slf *Endpoint) Link(conn *server.Conn) {
slf.connections.Set(conn.GetID(), conn)
}
// Unlink 断开连接
func (slf *Endpoint) Unlink(conn *server.Conn) {
slf.connections.Del(conn.GetID())
}
// GetLink 获取连接
func (slf *Endpoint) GetLink(id string) *server.Conn {
conn, _ := slf.connections.Get(id)
return conn
}
// 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 []byte, callback ...func(err error)) {
slf.client.Write(packet, callback...)
}
// WriteWS 写入 websocket 数据
func (slf *Endpoint) WriteWS(wst int, packet []byte, callback ...func(err error)) {
slf.client.WriteWS(wst, packet, callback...)
}
// onConnectionClosed 与端点连接断开事件
func (slf *Endpoint) onConnectionClosed(conn *client.Client, err any) {
if !slf.offline {
go slf.Connect()
}
}
// onConnectionReceivePacket 接收到来自端点的数据包事件
func (slf *Endpoint) onConnectionReceivePacket(conn *client.Client, wst int, packet []byte) {
addr, sendTime, packet, err := UnmarshalGatewayInPacket(packet)
if err != nil {
panic(err)
}
slf.state = slf.evaluator(float64(time.Now().UnixNano() - sendTime))
slf.GetLink(addr).SetWST(wst).Write(packet)
}