func makeSession() *Session { session := &Session{ Closer: closer.NewCloser(), Signaler: signaler.NewSignaler(), conns: make(map[uint32]*Conn), closedConnIds: list.New(), newTransport: make(chan Transport, 128), errTransport: make(chan Transport), incomingPackets: make(chan *Packet), incomingPacketsMap: make(map[string]*Packet), incomingAcks: make(chan *Packet), recvIn: make(chan *Packet), Recv: make(chan *Packet), outgoingPackets: make(chan *Packet), sendingPacketsMap: make(map[string]*Packet), outCheckTicker: time.NewTicker(time.Millisecond * 100), getTransportCount: make(chan int), getStatResend: make(chan int), } recvLink := ic.Link(session.recvIn, session.Recv) session.OnClose(func() { close(recvLink) session.CloseSignaler() }) session.setDebugEntries() go session.start() return session }
func newLogger() *Logger { logger := &Logger{ logsIn: make(chan string), Logs: make(chan string), } ic.Link(logger.logsIn, logger.Logs) logger.OnClose(func() { close(logger.logsIn) }) return logger }
func NewServer(addrStr string) (*Server, error) { ln, err := net.Listen("tcp", addrStr) if err != nil { return nil, err } server := &Server{ Closer: closer.NewCloser(), sessions: make(map[int64]*Session), newTransport: make(chan transportInfo), newSessionIn: make(chan *Session), NewSession: make(chan *Session), } l1 := ic.Link(server.newSessionIn, server.NewSession) server.OnClose(func() { ln.Close() // close listener close(l1) }) // accept go func() { for { transport, err := ln.Accept() if err != nil { if server.IsClosing { // close normally return } else { log.Fatal(err) } } go server.handleClient(transport) } }() // transport / session manager go func() { for { select { case <-server.WaitClosing: return case info := <-server.newTransport: session, ok := server.sessions[info.sessionId] if ok { // existing session session.newTransport <- info.transport } else { // new session session := server.newSession(info.sessionId, info.transport) server.sessions[info.sessionId] = session server.newSessionIn <- session } } } }() return server, nil }
func NewServer(addrStr string) (*Server, error) { addr, err := net.ResolveUDPAddr("udp", addrStr) if err != nil { return nil, err } udpConn, err := net.ListenUDP("udp", addr) if err != nil { return nil, err } server := &Server{ Logger: newLogger(), udpConn: udpConn, newConnsIn: make(chan *Conn), NewConns: make(chan *Conn), } ic.Link(server.newConnsIn, server.NewConns) server.OnClose(func() { server.udpConnClosed = true udpConn.Close() close(server.newConnsIn) }) go func() { // listen conns := make(map[string]*Conn) for { // read packet packetData := make([]byte, 1500) n, addr, err := udpConn.ReadFromUDP(packetData) if err != nil { if server.udpConnClosed { return } else { log.Fatalf("server read error %v", err) } } packetData = packetData[:n] server.Log("ReadFromUDP length %d", n) // dispatch key := addr.String() conn, ok := conns[key] if !ok { // new connection server.newConn(conns, addr, packetData) } else { conn.incomingPacketsIn <- packetData } } }() return server, nil }
func makeConn() *Conn { conn := &Conn{ serial: uint32(rand.Intn(65536)), Logger: newLogger(), incomingPacketsIn: make(chan []byte), incomingPackets: make(chan []byte), recvIn: make(chan []byte), Recv: make(chan []byte), unackPackets: list.New(), packetHeap: new(Heap), ackCheckTimer: NewTimer(time.Millisecond * 100), ackTimer: time.NewTimer(ackTimerTimeout), } heap.Init(conn.packetHeap) ic.Link(conn.incomingPacketsIn, conn.incomingPackets) ic.Link(conn.recvIn, conn.Recv) conn.OnClose(func() { conn.Logger.Close() close(conn.incomingPacketsIn) close(conn.recvIn) conn.ackCheckTimer.Close() }) return conn }