javascriptnode.jszebra-printers

Open a TCP/IP connection via socket with a label printer


I want to open a TCP/IP connection with a Zebra printer to send ZPL commands to print. I can do this with NodeJS but no with web sockets.

NodeJS

var s = require('net').Socket();
s.connect(9100, '192.168.0.99');
s.write(zpl_commands);

but can't send commands on websocket, I don't want to make a intermediary server with NodeJS that prints. Any idea if I can achieve this? I already try making a chrome plugin and didn't work.

My websocket code

const socket = new WebSocket('ws://192.168.0.99:9100');

socket.send(message);

I need to work with Chrome, because I connect a weight machine with a serial port. It's a possible solution to connect the printer into the computer via cable (but I would like via wifi, so I can print from several terminals) Note: if put in my browser ws://... I can connect to the printer 'printServer' Note2: The printer is a Zebra ZD420


Solution

  • As pointed out in my comment, the printer does not have a support for a WebSocket endpoint where you can send commands to it.

    Rather you have to write/use a proxy that creates a WebSocket/HTTP endpoint, which forwards the data send to it, to the underlaying TCP Socket connected to the printer.

    const { WebSocketServer, createWebSocketStream } = require("ws");
    const { Socket } = require("net");
    
    
    
    const { 
        WEBSOCKET_HOST, 
        WEBSOCKET_PORT, 
        PRINTER_HOST, 
        PRINTER_PORT 
    } = Object.assign({
        WEBSOCKET_HOST: "127.0.0.1",
        WEBSOCKET_PORT: "8320",
        PRINTER_HOST: "127.0.0.1",
        PRINTER_PORT: "1900"
    }, process.env);
    
    
    const server = new WebSocketServer({
        port: Number(WEBSOCKET_PORT),
        host: WEBSOCKET_HOST
    });
    
    
    server.once("listening", () => {
        console.log(`WebSocket server listening on ws://${WEBSOCKET_HOST}:${WEBSOCKET_PORT} for connections`);
    });
    
    
    server.on("connection", (ws) => {
    
        let socket = new Socket();
        let stream = createWebSocketStream(ws);
    
        socket.once("connect", () => {
            console.log("Connected to printer");
        });
    
        // pipe data from websocket to tcp socket
        // pipe data from tcp socket to websocket
        stream.pipe(socket);
        socket.pipe(stream);
    
        // connecto to printer via tcp socket
        socket.connect(Number(PRINTER_PORT), PRINTER_HOST);
    
    });
    

    The code above is very simple and straight forwarded.

    It creates a HTTP/WebSocket server/endpoint, where clients (like Browser, wscat, etc.) can connect to, which then creates a TCP Socket to the printer.

    You can test this with netcat & wscat.

    First, create a dummy tcp server/printer via: nc -l -p 1900. This tells netcat to create a tcp socket for incoming requests on the loopback interface (127.0.0.1) on port 1900.

    The start the WebSocket proxy above (after installing the websocket module via npm install ws): node tcp-ws-proxy.js.

    At last, connect via the WebSocket CLI client wscat --connect ws://127.0.0.1:8320 and enter some data, e.g. "Hello Netcat".

    What ever you enter, should be printed on the netcat console/terminal/output.

    This allows you to connect via a WebSocket client, like a Browser, to your printer.

    Modules/CLI tools used:

    Written & tested on Ubuntu 23.10, Node 20.11.0

    EDIT:

    Because Bergi mentioned it in the comments, i should have mentioned that you have to properly secure the WebSocket endpoint. Otherwise everyone could send print commands to the printer.