package microservice import ( "context" "fmt" "log" "net" "git.ali33.ru/fcg-xvii/go-tools/containers/concurrent" ) func NewServer(host string, port uint16, sockBufSize int, ctx context.Context, receiveBuf int) *Server { ctx, cancel := context.WithCancel(ctx) server := &Server{ ctx: ctx, cancel: cancel, host: host, port: port, chConnection: make(chan *Socket), sockets: concurrent.NewList(), receiveBuf: receiveBuf, } go server.start() return server } type Server struct { ctx context.Context cancel context.CancelFunc host string port uint16 sockBufSize int receiveBuf int listener net.Listener sockets *concurrent.List chConnection chan *Socket } func (s *Server) NewConnection() <-chan *Socket { return s.chConnection } func (s *Server) start() { go s.listen() <-s.ctx.Done() s.listener.Close() close(s.chConnection) } func (s *Server) listen() { var err error if s.listener, err = net.Listen("tcp", fmt.Sprintf("%v:%v", s.host, s.port)); err != nil { log.Fatal("Error starting all trade server:", err) } var conn net.Conn for { if conn, err = s.listener.Accept(); err != nil { //fmt.Println("Error accepting connection:", err) return } socket := NewSocket(conn, s.sockBufSize, s.ctx, s.receiveBuf) s.sockets.PushBack(socket) go func(sock *Socket) { <-sock.Context().Done() log.Println("close sock accepted....") if elem := s.sockets.Search(sock); elem != nil { log.Println("socket remove from list") s.sockets.Remove(elem) } log.Println(s.sockets.Size()) }(socket) s.chConnection <- socket } } func (s *Server) Close() { s.cancel() s.sockets.Each(func(val *concurrent.Element) bool { log.Println("CLOSE socket..........") val.Val().(*Socket).Close() return true }) }