github.com/Ryan-Johnson-1315/socketlogger@v0.0.2/server.go (about) 1 package socketlogger 2 3 import ( 4 "bufio" 5 "encoding/json" 6 "fmt" 7 "io" 8 "log" 9 "net" 10 "time" 11 ) 12 13 type Server interface { 14 Bind(c Connection) error 15 Shutdown() 16 17 start() 18 buildSocket(c Connection) (net.Conn, error) 19 listenForMsgsOnSocket(sock net.Conn, msgs chan SocketMessage) 20 getMessageType() SocketMessage 21 init(interface{}) 22 write(chan SocketMessage) // Either log file, csv file or console, implemented in server type 23 setFlushChannel(chan bool) 24 } 25 26 type server struct { 27 comms 28 msgs chan SocketMessage 29 this interface{} 30 closeSockets chan bool // This channel will notify to close the sockets 31 flushed chan bool // This makes Shutdown() blocking, allowing everything to be written to console/log file 32 } 33 34 func (s *server) Bind(c Connection) error { 35 var err error = nil 36 s.sock, err = s.this.(Server).buildSocket(c) 37 if err != nil { 38 return err 39 } else { 40 s.start() 41 return nil 42 } 43 } 44 45 func (s *server) Shutdown() { 46 close(s.closeSockets) 47 close(s.msgs) // Notifies writer to finish writing 48 <-s.flushed // Waits for writer to flush all data 49 } 50 51 func (s *server) init(i interface{}) { 52 if inst, ok := i.(Server); !ok { 53 panic(fmt.Errorf("instance is not of type Server! Type: %T", inst)) 54 } else { 55 s.msgs = make(chan SocketMessage, 100) 56 s.this = i 57 s.closeSockets = make(chan bool) 58 s.flushed = make(chan bool) 59 } 60 } 61 62 func (s *server) start() { 63 s.this.(Server).setFlushChannel(s.flushed) 64 go s.this.(Server).write(s.msgs) 65 go s.listenForMsgsOnSocket(s.comms.sock, s.msgs) 66 } 67 68 func (s *server) listenForMsgsOnSocket(sock net.Conn, msgs chan SocketMessage) { 69 if sock != nil { 70 reader := bufio.NewReaderSize(sock, bufSize) 71 dec := json.NewDecoder(reader) 72 inst, ok := s.this.(Server) 73 if !ok { 74 panic(fmt.Errorf("server is not a Sever type. Type %T", inst)) 75 } 76 77 decoded := make(chan SocketMessage, 100) 78 running := true 79 socketDisconnected := make(chan bool) 80 go func() { 81 for { 82 msg := inst.getMessageType() 83 if err := dec.Decode(&msg); err != nil { 84 if running && err == io.EOF { 85 time.Sleep(50 * time.Nanosecond) // Make sure this message gets printed last 86 s.msgs <- newLogMessage(MessageLevelDbg, "Socket disconnected %s", sock.RemoteAddr()) 87 } else if running { 88 s.msgs <- newLogMessage(MessageLevelErr, "ERROR!! %v, unexpected error: %v", err, running) 89 } 90 sock.Close() 91 break 92 } else { 93 decoded <- msg 94 } 95 } 96 socketDisconnected <- true 97 }() 98 99 L: 100 for { 101 select { 102 case msg := <-decoded: 103 msgs <- msg 104 case <-s.closeSockets: 105 running = false 106 break L 107 } 108 } 109 sock.Close() 110 <-socketDisconnected 111 } 112 } 113 114 type udpserver struct { 115 server 116 } 117 118 func (u *udpserver) buildSocket(c Connection) (net.Conn, error) { 119 sock, err := net.ListenUDP(udpProtocol, &net.UDPAddr{ 120 IP: net.ParseIP(c.Addr), 121 Port: c.Port, 122 }) 123 if err != nil { 124 log.Println(newLogMessage(MessageLevelErr, "Could not create %s: %v", "UDP Server", err)) 125 } else { 126 log.Println(newLogMessage(MessageLevelSuccess, "%s listening at %s", "UDP Server", sock.LocalAddr())) 127 } 128 129 return sock, err 130 } 131 132 type tcpserver struct { 133 server 134 } 135 136 // Satisfies Server interface 137 func (t *tcpserver) buildSocket(c Connection) (net.Conn, error) { 138 var err error 139 var listener net.Listener 140 listener, err = net.Listen("tcp", fmt.Sprintf("%v:%d", c.Addr, c.Port)) 141 if err == nil { 142 log.Println(newLogMessage(MessageLevelSuccess, "%s listening at %s:%d", "TCP Server", c.Addr, c.Port)) 143 go func() { 144 defer listener.Close() 145 for { 146 // Listen for an incoming connection. 147 conn, err := listener.Accept() 148 if err != nil { 149 log.Println(newLogMessage(MessageLevelErr, "Error accepting: %v", err.Error()).String()) 150 continue 151 } 152 153 go t.this.(Server).listenForMsgsOnSocket(conn, t.msgs) 154 } 155 }() 156 } 157 158 return nil, err 159 }