|
|
package connection
|
|
|
|
|
|
import (
|
|
|
"net"
|
|
|
"sync"
|
|
|
"time"
|
|
|
|
|
|
"github.com/rs/xid"
|
|
|
)
|
|
|
|
|
|
// UDPConnection UDP连接包装器
|
|
|
type UDPConnection struct {
|
|
|
id string
|
|
|
addr *net.UDPAddr
|
|
|
conn *net.UDPConn
|
|
|
mu sync.RWMutex
|
|
|
createdAt time.Time
|
|
|
lastActive time.Time
|
|
|
attributes map[string]interface{}
|
|
|
}
|
|
|
|
|
|
// NewUDPConnection 创建UDP连接
|
|
|
// 如果id为空,将自动生成唯一的xid
|
|
|
func NewUDPConnection(id string, addr *net.UDPAddr, conn *net.UDPConn) *UDPConnection {
|
|
|
if id == "" {
|
|
|
id = xid.New().String()
|
|
|
}
|
|
|
return &UDPConnection{
|
|
|
id: id,
|
|
|
addr: addr,
|
|
|
conn: conn,
|
|
|
createdAt: time.Now(),
|
|
|
lastActive: time.Now(),
|
|
|
attributes: make(map[string]interface{}),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// ID 获取连接ID
|
|
|
func (c *UDPConnection) ID() string {
|
|
|
return c.id
|
|
|
}
|
|
|
|
|
|
// RemoteAddr 获取远程地址
|
|
|
func (c *UDPConnection) RemoteAddr() string {
|
|
|
if c.addr != nil {
|
|
|
return c.addr.String()
|
|
|
}
|
|
|
return ""
|
|
|
}
|
|
|
|
|
|
// LocalAddr 获取本地地址
|
|
|
func (c *UDPConnection) LocalAddr() string {
|
|
|
if c.conn != nil {
|
|
|
return c.conn.LocalAddr().String()
|
|
|
}
|
|
|
return ""
|
|
|
}
|
|
|
|
|
|
// Write 写入数据
|
|
|
// 如果设置了gnet_conn属性,使用gnet.Conn的Write方法(gnet会自动处理UDP目标地址)
|
|
|
// 否则使用传统的WriteToUDP方法
|
|
|
func (c *UDPConnection) Write(data []byte) error {
|
|
|
c.mu.Lock()
|
|
|
c.lastActive = time.Now()
|
|
|
|
|
|
// 检查是否有gnet.Conn(通过属性传递)
|
|
|
gnetConn := c.attributes["gnet_conn"]
|
|
|
c.mu.Unlock()
|
|
|
|
|
|
// 如果使用gnet,通过gnet.Conn的Write方法发送
|
|
|
// gnet会自动处理UDP的目标地址(因为gnet.Conn已经绑定了远程地址)
|
|
|
if gnetConn != nil {
|
|
|
// gnet.Conn应该有Write方法
|
|
|
if writer, ok := gnetConn.(interface {
|
|
|
Write([]byte) error
|
|
|
}); ok {
|
|
|
return writer.Write(data)
|
|
|
}
|
|
|
// 如果gnet.Conn有SendTo方法(UDP专用),优先使用
|
|
|
if sendTo, ok := gnetConn.(interface {
|
|
|
SendTo([]byte) error
|
|
|
}); ok {
|
|
|
return sendTo.SendTo(data)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 回退到传统的WriteToUDP
|
|
|
if c.conn != nil && c.addr != nil {
|
|
|
_, err := c.conn.WriteToUDP(data, c.addr)
|
|
|
return err
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
// Close 关闭连接(UDP连接通常不需要关闭)
|
|
|
func (c *UDPConnection) Close() error {
|
|
|
// UDP是无连接的,这里不做实际关闭操作
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
// SetAttribute 设置属性
|
|
|
func (c *UDPConnection) SetAttribute(key string, value interface{}) {
|
|
|
c.mu.Lock()
|
|
|
defer c.mu.Unlock()
|
|
|
if c.attributes == nil {
|
|
|
c.attributes = make(map[string]interface{})
|
|
|
}
|
|
|
c.attributes[key] = value
|
|
|
}
|
|
|
|
|
|
// GetAttribute 获取属性
|
|
|
func (c *UDPConnection) GetAttribute(key string) interface{} {
|
|
|
c.mu.RLock()
|
|
|
defer c.mu.RUnlock()
|
|
|
if c.attributes == nil {
|
|
|
return nil
|
|
|
}
|
|
|
return c.attributes[key]
|
|
|
}
|
|
|
|
|
|
// LastActive 获取最后活动时间
|
|
|
func (c *UDPConnection) LastActive() time.Time {
|
|
|
c.mu.RLock()
|
|
|
defer c.mu.RUnlock()
|
|
|
return c.lastActive
|
|
|
}
|
|
|
|
|
|
// UpdateActive 更新活动时间
|
|
|
func (c *UDPConnection) UpdateActive() {
|
|
|
c.mu.Lock()
|
|
|
defer c.mu.Unlock()
|
|
|
c.lastActive = time.Now()
|
|
|
}
|
|
|
|