예제 #1
0
파일: session.go 프로젝트: reusee/van
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
}
예제 #2
0
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
}
예제 #3
0
파일: server.go 프로젝트: reusee/van
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
}
예제 #4
0
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
}
예제 #5
0
파일: conn.go 프로젝트: reusee/reliable-udp
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
}