Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement own client using ttyd only on server side #1400

Open
sreisich opened this issue Sep 26, 2024 · 4 comments
Open

Implement own client using ttyd only on server side #1400

sreisich opened this issue Sep 26, 2024 · 4 comments
Labels

Comments

@sreisich
Copy link

sreisich commented Sep 26, 2024

Is there a way to implement ttyd's client side in my own application? I mean, implement xterm.js in my own application that connects to the websocket provided by ttyd?
What would the vanilla js code look like?

If this is technically possible, I would really like to sponsor this project. Please let me know what you think.

@tsl0922
Copy link
Owner

tsl0922 commented Oct 5, 2024

Sure, as long as you implement ttyd's websocket protocol, it's pretty simple.

enum Command {
// server side
OUTPUT = '0',
SET_WINDOW_TITLE = '1',
SET_PREFERENCES = '2',
// client side
INPUT = '0',
RESIZE_TERMINAL = '1',
PAUSE = '2',
RESUME = '3',
}

@sreisich
Copy link
Author

sreisich commented Oct 5, 2024

Glad to hear that, thanks.
If you like, I would like to sponsor a fully working vanilla javascript example. Would you be open to such an offer? I mean, I'm not a javascript pro and you know how to do it... I would like to sponsor an example index.html with vanilla js showing how an external page could connect to the ttyd socket. If you like, you can include this example here in the project, or anywhere, as open source code. Others might be interested in it too.
If you are interested, let me know how I can contact you privately to talk about sponsoring...

@tsl0922
Copy link
Owner

tsl0922 commented Oct 16, 2024

Why not just copy the code in this project?

If you really want a vanilla javascript example, I would recommend you to take a look at xterm.js's demo:
https://github.com/xtermjs/xterm.js/tree/master/demo

@gabrield
Copy link

gabrield commented Apr 1, 2025

Sure, as long as you implement ttyd's websocket protocol, it's pretty simple.

ttyd/html/src/components/terminal/xterm/index.ts

Lines 25 to 36 in 40e79c7

enum Command {
// server side
OUTPUT = '0',
SET_WINDOW_TITLE = '1',
SET_PREFERENCES = '2',
// client side
INPUT = '0',
RESIZE_TERMINAL = '1',
PAUSE = '2',
RESUME = '3',
}

There is a working example of that? I tried to implement ttyd's protocol but coud not get it working:


const WebSocket = require('ws');
const ws = new WebSocket("ws://127.0.0.1:8003");
ws.binaryType = "arraybuffer"; // Expect binary data

ws.onopen = () => {
    console.log("✅ Connected to ttyd!");

    setTimeout(() => {
        if (ws.readyState === WebSocket.OPEN) {
            console.log("📤 Sending command: ls");
            ws.send(new Uint8Array([0x00, ...new TextEncoder().encode("ls\n")]));
        } else {
            console.warn("⚠️ WebSocket not open. Cannot send data.");
        }
    }, 500); // Wait a little before sending
};

ws.onmessage = (event) => {
    console.log("📥 Raw Data Received:", event.data); // Debug raw data

    const data = new Uint8Array(event.data);
    if (data.length === 0) {
        console.warn("⚠️ Received empty message!");
        return;
    }

    const type = data[0]; // Extract message type
    console.log("📥 Message Type:", type);

    switch (type) {
        case 0x01: // Terminal output
            console.log("📥 Terminal Output:\n" + new TextDecoder().decode(data.slice(1)));
            break;
        case 0x05: // Window title change
            console.log("🖥️ Window Title Changed:", new TextDecoder().decode(data.slice(1)));
            break;
        default:
            console.warn("⚠️ Unknown message type:", type);
    }
};

ws.onerror = (error) => {
    console.error("❌ WebSocket Error:", error);
};

ws.onclose = (event) => {
    console.log(`🔌 Connection closed (Code: ${event.code}, Reason: ${event.reason})`);
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants