package core import ( "bufio" "context" "fmt" "log/slog" "net" ) type Server struct { l *slog.Logger port string ctx context.Context Sessions chan *Session ln net.Listener } func NewServer(ctx context.Context, l *slog.Logger, port string) *Server { var s Server // TODO: Check for context cancellation and cleanup c := make(chan *Session) s.Sessions = c ln, err := net.Listen("tcp", port) if err != nil { s.l.With( slog.Any("error", err), ).Error("could not start tcp listener") return &s } s.ctx = ctx s.ln = ln s.l = l s.port = port return &s } func (s *Server) Start() { s.l.Debug("starting telnet server") // TODO: Check for context cancellation and cleanup for { conn, err := s.ln.Accept() if err != nil { s.l.With( slog.Any("error", err), ).Error("could not accept tcp connection") } s.Sessions <- NewSession(s.ctx, conn, Printer{}, s.l) } } type Session struct { c net.Conn ctx context.Context p Printer l *slog.Logger userID uint64 } func NewSession(ctx context.Context, c net.Conn, p Printer, l *slog.Logger) *Session { return &Session{ ctx: ctx, l: l, p: p, c: c, } } func (s *Session) Start() { s.l.Debug("starting telnet session") fmt.Fprint(s.c, "Welcome to Bing Bong.\n") scanner := bufio.NewScanner(s.c) var line string for { select { case <-s.ctx.Done(): s.l.Error("cancelled") return default: if scanner.Scan() { line = scanner.Text() fmt.Fprintf(s.c, "> %q\n", line) } // a.L.Info("scanning input") s.l.With(slog.String("input", line)).Info("received command") } } }