I’m using node-pty
& I have a socket.io server, and I’m trying to run a terminal for the client to communicate with. It mostly works, except for one issue where the onData listener doesn’t fire when writing to my terminal.
terminal.ts
import { spawn, IPty } from "node-pty"
import { Socket } from "socket.io"
import os from "os"
export class Pty {
socket: Socket
ptyProcess: IPty
shell: string
constructor(socket: Socket, id: string) {
this.socket = socket
this.shell = os.platform() === "win32" ? "cmd.exe" : "bash"
this.ptyProcess = spawn(this.shell, [], {
name: "xterm",
cols: 100,
cwd: `/temp`,
})
this.ptyProcess.onData((data) => {
console.log("onData", data)
this.send(data)
})
this.write("hello")
}
write(data: string) {
console.log("writing data", data)
this.ptyProcess.write(data)
}
send(data: string) {
this.socket.emit("terminalResponse", {
data: Buffer.from(data, "utf-8"),
})
}
}
sockets.ts (very simplified)
const terminals: { [id: string]: Pty } = {}
io.on("connection", async (socket) => {
const data = socket.data as {
userId: string
id: string
}
socket.on("createTerminal", ({ id }: { id: string }) => {
terminals[id] = new Pty(socket, id)
})
socket.on("terminalData", ({ id, data }: { id: number; data: string }) => {
if (!terminals[id]) {
console.log("terminal not found")
return
}
terminals[id].write(data)
})
})
In the constructor of terminal.ts
, I run this.write("hello")
and it works as expected (triggers onData and emits the terminalResponse socket event).
In the sockets.ts
file, the createTerminal
listener works properly. The terminalData
listener calls the write
function on a terminal but it doesn’t execute the onData function.
Why is the behaviour different, and what’s causing it?