Suck the cat with code! This paper is participating in[Cat Essay Campaign]

preface

When it comes to using web pages to open terminals, I believe that most people have used them, but there should be few people to seriously study πŸ€”. I also need to work, so I explored it.

If you have ever used a cloud server, you are certainly familiar with this, such as Ali Cloud Workbench remote connection. It provides us with service convenience, user experience is still quite good, let us and the actual machine through the network connectivity.

In addition, there are many other things that can run on the browser, such as cloud documents, cloud software, cloud IDES, cloud storage and so on……

Now let’s do a small task: open the terminal with a web page, and then input small_cat command in the terminal, in the terminal output a group of kittens 🐱.

Fast implementation (just two steps πŸš€ + browser access)

There are already mature component libraries that implement web terminals based on Xterm.js, such as WebSSH (More Real world Uses), which can connect to your server from a web page in just two steps. There is no surprise 😁

1. Performpip install webssh, install webssh

First make sure you have Python installed on your computer and version 2.7/3.4+

But python3 is actually used anyway (pythond+ PIP installation error, possibly because Python and PIP versions do not match).

If you are using a MAC, you can check to see if PYTHon3 exists, as follows:

Python 2.7.16 python3 --version or /usr/bin/python3 --version -> Python 3.9.5Copy the code

Python3 can be executed directly if python3 is available (PIP can be upgraded if there is an error) :

Python3 -m PIP install webssh/pip3 install webssh Sudo /usr/bin/python3 -m PIP install webssh --upgrade PIP // python3 -m PIP install websshCopy the code

2. Start the WebSSH service

Enter WSSH in the terminal to access the browser locally.

(Of course, running WSSH hogs processes. If you are deploying to a production environment, you need to run it in the background and enable process daemons.)

For more information, see webssh: github.com/huashengdun…

3. How do you draw a cat?

The answer to this question may surprise you πŸ‘“—- is consoleπŸ˜„. You can use console to output character images as well as background patterns. (You can also use echo, which is a script executed by shell.)

At this point, the little task is done.

Of course, if you are the pursuit of technology partners, want to implement their own extension of some functions, it is also no problem. Take a look below:

Do it yourself

It has been discovered that most of the browser open terminal solutions use Xterm.js, which is used by popular projects such as VS Code, Hyper and Theia. In addition to providing basic functions, it also provides many terminal related plug-ins. Let’s use it to achieve their own web terminal.

1. Install and run according to the official documents[Xtermjs document address]

NPM install xterm: <! doctype html> <html> <head> <link rel="stylesheet" href="node_modules/xterm/css/xterm.css" /> <! - also can directly use the CDN using xterm static resources -- -- > < script SRC = "/ node_modules xterm/lib/xterm. Js" > < / script > < / head > < body > < div id="terminal"></div> <script> var term = new Terminal(); term.open(document.getElementById('terminal')); term.write('Hello from \x1B[1;3;31mxterm.js\x1B[0m $ ') </script> </body> </html>Copy the code

2. Characters cannot be entered in the customer service

Failed to enter any characters in the browser terminal. We need to listen for each input:

Term.write ('Hello from \x1B[1;3;31mxterm.js\x1B[0m $') // Need to add in script: term.ondata ((value)=>{term.write(value)})Copy the code

3. The delete key is invalid, and the cursor moves to the first character when you press Enter

Try again and find that you can input, but cannot delete the entered character. Continue to check the document and find that there is a coding problem, unable to identify the delete key. As documented, input is compiled using Node-pty, which is a Node.js-based solution.

The logic is as follows: any input instruction from the client is passed to the back end through websocket ==> Compiled in the back end virtual terminal, and the result is returned to the client through websocket.

4. Server virtual terminal (receiving and converting input from client)

Concrete implementation of browser side (complete) :

<! doctype html> <html> <head> <link rel="stylesheet" href="node_modules/xterm/css/xterm.css" /> <script SRC = "/ node_modules xterm/lib/xterm. Js" > < / script > < script SRC = "https://www.unpkg.com/[email protected]/dayjs.min.js" > < / script > < script SRC = "https://www.unpkg.com/[email protected]/lib/xterm-addon-attach.js" > < / script > < / head > < body > < div id="terminal"></div> <script> var term = new Terminal(); term.open(document.getElementById('terminal')); Term. The focus () const socketURL = "ws: / / 127.0.0.1:3030 / socket"; const ws = new WebSocket(socketURL); attachAddon = new AttachAddon.AttachAddon(ws); term.loadAddon(attachAddon); </script> </body> </html> <! -->Copy the code

Server side implementation (complete) :

#! /usr/bin/env node var express = require('express'); var app = express(); const pty = require("node-pty"); require('express-ws')(app); const os = require("os"); const shell = os.platform() === "win32" ? "powershell.exe" : "bash"; App.ws ("/socket", (ws, req) => {console.log('websocket connection succeeded ') // Generate term every time you connect. Spawn (shell, ["--login"], {name: "xterm", cols: 50, rows: {name: "xterm", cols: 50, rows: 24, cwd: process.env.HOME, env: process.env, }); ws.on("open", (data) => { console.log('open data===', data) }); Term. on("data", function (data) {console.log(' data sent to client ===', data) ws.send(data); }); On ("message", (data) => {console.log(' receive data from customer service ===', data) term.write(data); }); ws.on("close", function () { term.kill(); }); }); app.listen(3030); // Copy can be directly used locallyCopy the code

Note that the client generates a term every time it connects to the server. Therefore, the socket needs to be initialized every time it connects to the server. Otherwise, the term on the server will be disconnected when the customer side refreshes the page

At present, we have realized the basic functions of the web terminal, the official website also provides a lot of interesting plug-ins, interested partners can try! (More real-world Uses)

The main content of the article has been completed, and I will continue to add some related content about Linux named line operation and VIM shortcut operation. Those who are interested can add favorites (Ctrl + D or Command + D) in case they need them.


The last

If we do not have a complete idea of some problems, we may as well try to achieve. In the realization of the process to find methods, summed up experience. Implementation should not be abandoned or considered impossible without trying.

If you find it helpful, you can like it and support it. If you have any questions or suggestions, please leave them at πŸ‘‡πŸ». Thank you very much.

Author: Tager Address: juejin.cn/user/435372… Copyright belongs to the author. Commercial reprint please contact the author for authorization, non-commercial reprint please indicate the source.