server.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package microservice
  2. import (
  3. "context"
  4. "fmt"
  5. "log"
  6. "net"
  7. "git.ali33.ru/fcg-xvii/go-tools/containers/concurrent"
  8. )
  9. func NewServer(host string, port uint16, sockBufSize int, ctx context.Context) *Server {
  10. ctx, cancel := context.WithCancel(ctx)
  11. server := &Server{
  12. ctx: ctx,
  13. cancel: cancel,
  14. host: host,
  15. port: port,
  16. chConnection: make(chan *Socket),
  17. sockets: concurrent.NewList(),
  18. }
  19. go server.start()
  20. return server
  21. }
  22. type Server struct {
  23. ctx context.Context
  24. cancel context.CancelFunc
  25. host string
  26. port uint16
  27. sockBufSize int
  28. listener net.Listener
  29. sockets *concurrent.List
  30. chConnection chan *Socket
  31. }
  32. func (s *Server) NewConnection() <-chan *Socket {
  33. return s.chConnection
  34. }
  35. func (s *Server) start() {
  36. go s.listen()
  37. <-s.ctx.Done()
  38. s.listener.Close()
  39. close(s.chConnection)
  40. }
  41. func (s *Server) listen() {
  42. var err error
  43. if s.listener, err = net.Listen("tcp", fmt.Sprintf("%v:%v", s.host, s.port)); err != nil {
  44. log.Fatal("Error starting all trade server:", err)
  45. }
  46. var conn net.Conn
  47. for {
  48. if conn, err = s.listener.Accept(); err != nil {
  49. //fmt.Println("Error accepting connection:", err)
  50. return
  51. }
  52. socket := NewSocket(conn, s.sockBufSize, s.ctx)
  53. s.sockets.PushBack(socket)
  54. go func(sock *Socket) {
  55. <-sock.Context().Done()
  56. log.Println("close sock accepted....")
  57. if elem := s.sockets.Search(sock); elem != nil {
  58. log.Println("socket remove from list")
  59. s.sockets.Remove(elem)
  60. }
  61. log.Println(s.sockets.Size())
  62. }(socket)
  63. s.chConnection <- socket
  64. }
  65. }
  66. func (s *Server) Close() {
  67. s.cancel()
  68. s.sockets.Each(func(val *concurrent.Element) bool {
  69. log.Println("CLOSE socket..........")
  70. val.Val().(*Socket).Close()
  71. return true
  72. })
  73. }