You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
2.9 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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()
}