ASCII String -> Input Issue

Hello all,

I am trying to emulate a terminal within an app. Currently, I am using Socket.io to communicate between the server-side node-pty, and the client-side React input element.

The trouble I am having is when I send data from the server:

ptyProcess.onData((data) => {
    console.log("server: ", data);
    io.emit("term.incData", data);
  });

data is logged in the console as I expect it to be:

server:  cd Documents

It is coming malformed in the frontend:

e[93mcde[m Documentse[?25h

Here is the frontend logic:

const Console = (props) => {
  const [text, setText] = useState("");
  const socket = io();
  useEffect(() => {
    socket.emit("term.toTerm", text);
  }, []);
  const handleInput = (e) => {
    console.log("console 1: ", e);
    setText(e.target.value);
  };

// Separate logic for "Enter" keyCode
  const handleEnter = (e) => {
    if (e.which == 13) {
      socket.emit("term.toTerm", stripTerminal(text) + String.fromCharCode(13));
    }
  };

  function stripTerminal(text) {
    const test = text.replace(/PS.*?>/, "");
    return test;
  }

  socket.on("term.incData", (data) => {
    console.log("console 2: ", typeof data, data); // Malformed here
    setText(data);
  });
  return (
    <div id="console">
      <input
        type="text"
        value={text}
        onChange={handleInput}
        onKeyPress={handleEnter}
      ></input>
    </div>
  );
};
More Code (Server)
const ptyProcess = pty.spawn(shell, [], {
  name: "xterm-color",
  cols: 80,
  rows: 30,
  cwd: process.env.HOME,
  env: process.env,
});

io.on("connection", (socket) => {
  ptyProcess.onData((data) => {
    console.log("server: ", data);
    io.emit("term.incData", data);
  });

  socket.on("term.toTerm", (e) => {
    console.log("server 2: ", e);
    ptyProcess.write(e);
  });

  socket.on("disconnect", () => {
    console.log("A user has disconnected");
  });
});
If complete client logs helps
console 2:  string e[?25l
console 2:  string e[93mcde[m Documentse[?25h
console 2:  string e[?25l
console 2:  string e[93mcde[m Documentse[?25h
console 2:  string e[?25l
console 2:  string e[93mcde[m Documentse[?25h
console 2:  string e[?25l
console 2:  string e[93mcde[m Documentse[?25h
console 2:  string e[?25l
console 2:  string e[93mcde[m Documentse[?25h
console 2:  string e[?25l
console 2:  string e[93mcde[m Documentse[?25h
console 2:  string e[?25l
console 2:  string e[93mcde[m Documentse[?25h
console 2:  string e[?25l
console 2:  string e[93mcde[m Documentse[?25h


document.querySelector("#console > input").value
"e[93mcde[m Documentse[?25h"
document.querySelector("#console > input").value.charCodeAt(0)
27
document.querySelector("#console > input").value.charCodeAt(1)
91
document.querySelector("#console > input").value.charCodeAt(2)
57

As this app is mostly set up for running using Tauri, it would be difficult to get a sample running in Repl.it, or CodeSandbox. :frowning:

Any ideas why the string is coming through malformed, and how to best correct the data being returned?

Perhaps is a dumb question, but have you tried setting the socket encoding?

socket.setEncoding('utf8');

Thank you, @Marmiz,

That is not a stupid question at all. I did not try that. However, as I am not using straight WebSockets, it is not as simple as setting a property…Socket.io is surprisingly different. So, the closest I am getting is:

socket.emit('with-binary', 1, '2', { 3: '4', 5: Buffer.from([6]) });

Which is not working the way I expect on the client side

I have managed to sort the issue. I am unsure what actually resolved the issue, but what I needed to change:

  1. Change Console component into a pure component and memoize it - prevent re-rendering.
  2. Send data server :left_right_arrow: client as stringified JSON.

React re-rendering as much as it wants is no joke.

That make sense, but still does not address the original issue, I think that Socket.io handles string data out of the box. So there must have been some other factor at play interfering with it :thinking:

Regardless, I’m glad to hear you sorted out in the end. :sparkles:

1 Like