Files
2026-09-30 10:22:42 +02:00

66 lines
1.3 KiB
Go

// Package lan expone la impresora por TCP en modo RAW (puerto 9100,
// también llamado JetDirect / AppSocket), como las impresoras de red reales.
package lan
import (
"errors"
"net"
"escpos-emulator/internal/escpos"
)
// Server acepta conexiones TCP y entrega los bytes a la impresora.
type Server struct {
ln net.Listener
printer *escpos.Printer
}
// Listen abre el puerto y empieza a aceptar conexiones en segundo plano.
func Listen(addr string, p *escpos.Printer) (*Server, error) {
ln, err := net.Listen("tcp", addr)
if err != nil {
return nil, err
}
s := &Server{ln: ln, printer: p}
go s.serve()
return s, nil
}
// Addr devuelve la dirección en la que escucha.
func (s *Server) Addr() net.Addr { return s.ln.Addr() }
// Close deja de aceptar conexiones.
func (s *Server) Close() error { return s.ln.Close() }
func (s *Server) serve() {
for {
conn, err := s.ln.Accept()
if err != nil {
if errors.Is(err, net.ErrClosed) {
return
}
continue
}
go s.handle(conn)
}
}
func (s *Server) handle(conn net.Conn) {
defer conn.Close()
session := s.printer.NewSession("LAN "+conn.RemoteAddr().String(), func(b []byte) {
_, _ = conn.Write(b)
})
defer session.Close()
buf := make([]byte, 4096)
for {
n, err := conn.Read(buf)
if n > 0 {
session.Write(buf[:n])
}
if err != nil {
return
}
}
}