package main import ( "io" "log" "net" "sync" ) type PacketQueue struct { mu sync.RWMutex expectedPackages map[uint32]*Listener } type CallResult struct { StatusCode uint32 Data []byte } type Listener struct { Count int Chan chan CallResult } func NewPacketQueue(connection net.Conn) *PacketQueue { queue := &PacketQueue{ expectedPackages: make(map[uint32]*Listener), } go queue.HandleConnection(connection) return queue } func (p *PacketQueue) HandleConnection(connection net.Conn) error { defer connection.Close() var packet Packet for { err := ReadPacket(connection, &packet) if err != nil { if err == io.EOF { return nil } log.Printf("Error receiving packet: %v\n", err) return err } if packet.Version != CurrentPacketVersion { log.Printf("Error receiving packet: %v\n", err) continue } if packet.DataLength == 0 { go p.HandleData(packet.MessageType, CallResult{ StatusCode: packet.StatusCode, Data: []byte{}, }) continue } data, err := GetPacketData(connection, packet.DataLength) if err != nil { log.Printf("Error receiving packet data: %v\n", err) //return err } else { go p.HandleData(packet.MessageType, CallResult{ StatusCode: packet.StatusCode, Data: data, }) } } } func (p *PacketQueue) HandleData(t uint32, data CallResult) { p.mu.Lock() defer p.mu.Unlock() l, ok := p.expectedPackages[t] if ok { l.Chan <- data l.Count-- if l.Count == 0 { close(l.Chan) delete(p.expectedPackages, t) } return } } func (p *PacketQueue) Expect(messageType uint32) <-chan CallResult { p.mu.Lock() defer p.mu.Unlock() l, ok := p.expectedPackages[messageType] if ok { l.Count++ return l.Chan } ch := make(chan CallResult) p.expectedPackages[messageType] = &Listener{ Count: 1, Chan: ch, } return ch }