66 lines
1.3 KiB
Go
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
|
|
}
|
|
}
|
|
}
|