diff --git a/ipgeo/leo.go b/ipgeo/leo.go index ba09ca2..c9e3d0b 100644 --- a/ipgeo/leo.go +++ b/ipgeo/leo.go @@ -83,6 +83,11 @@ func receiveParse() { } } +// 当前的实现中,每次调用 receiveParse() 都会锁定 WebSocket 连接 +// 当前为单例模式,只启动一个 receiveParse 协程 + +var receiveParseOnce sync.Once + func LeoIP(ip string, timeout time.Duration, lang string, maptrace bool) (*IPGeoData, error) { // TODO: 根据lang的值请求中文/英文API // TODO: 根据maptrace的值决定是否请求经纬度信息 @@ -100,7 +105,10 @@ func LeoIP(ip string, timeout time.Duration, lang string, maptrace bool) (*IPGeo // 发送请求 sendIPRequest(ip) // 同步开启监听 - go receiveParse() + // 确保 receiveParse 只启动一次 + receiveParseOnce.Do(func() { + go receiveParse() + }) // 拥塞,等待数据返回 select { diff --git a/trace/packet_listener.go b/trace/packet_listener.go index 6bc9184..f957b99 100644 --- a/trace/packet_listener.go +++ b/trace/packet_listener.go @@ -13,12 +13,17 @@ type ReceivedMessage struct { Err error } +// PacketListener 负责监听网络数据包并通过通道传递接收到的消息 type PacketListener struct { ctx context.Context Conn net.PacketConn Messages chan ReceivedMessage } +// NewPacketListener 创建一个新的数据包监听器 +// conn: 用于接收数据包的连接 +// ctx: 用于控制监听器生命周期的上下文 +// 返回初始化好的 PacketListener 实例 func NewPacketListener(conn net.PacketConn, ctx context.Context) *PacketListener { results := make(chan ReceivedMessage, 50)