2013-10-24 94 views
16

我已经阅读了关于Fabrice Bellard在浏览器中的linux模拟。在浏览器中模拟linux终端

How does Linux emulator in Javascript by Fabrice Bellard work?

今天我偶然发现了这个网站,他们在那里模拟完整的Linux终端的浏览器,我能够运行python,perl的等,我知道他们是在node.js中运行自己的网站,但我无法弄清楚他们如何精确模拟终端。

http://runnable.com/UWRl3KlLuONCAACG/read-files-from-filesystem-in-python

+3

通过ajax请求...尝试打开Firefox的Web控制台,你可以看到一系列的Ajax请求:-) – Hellgorithm

回答

21

完整的linux是http://docker.io,其余为https://github.com/Runnable/dockworker

我们不是模拟终端,但凯尔说,复制过的WebSockets终端(与阿贾克斯回退)。

在浏览器中,我们使用的是来自Fabrice Bellard模拟器的https://github.com/chjj/term.js。它处理输出,还有按键捕捉。

+0

完美..我正在寻找这样的事情。 – DevC

+2

我有一个服务nodechool.io研讨会的简化版本:https://github.com/generalhenry/expose-bash-over-websockets https://github.com/generalhenry/nodeschool-interactive https://github.com/generalhenry/docker-gc https://github.com/generalhenry/nodeschool-dockerfiles – generalhenry

+0

这个问题是从4年前,但我实际上试图做到这一点,我卡住了...有人有一个想法如何把一个Docker终端放在Meteor应用程序中?我创建了https://github.com/mafintosh/docker-browser-console,但我无法让它适用于我。我会感谢任何帮助 – Jerome

4

让我说这不是一个好主意,做这个前缀此。

但是,您可以生成一个shell并使用web-sockets或XMLHttpRequests将按键压入生成的服务器进程。这是一个在Windows上运行的示例。不幸的是,我没有想办法解决/搞清楚Ctrl + c。但是,你应该知道它的要点。

require("underscore"); 

    var Server = {}, 
     express = require("express"), 
     path = require("path"), 
     sys = require("sys"), 
     application_root = __dirname; 

    global.Server = Server; 
    Server.root = application_root; 
    global.app = express(); 

    Server.setup = require("./lib/setup.js").setup({ 
    //redis: require("./lib/redis-client").createClient(), 
    app: app, 
    //mongoose : require("mongoose"), 
    io : require("socket.io"), 
    express : express, 
    port: 1773, 
    paths : { 
     views : path.join(application_root,"app","views"), 
     root : path.join(application_root,"public"), 
     controllers : path.join(application_root,"app","controllers"), 
     models : path.join(application_root,"app","models") 
    } 
    }); 

    var proc = require('child_process'), 
     cmd; 

    app.socket.on('connection', function(socket) { 
    if (!cmd) { 
     //console.log('spawning cmd'); 
     cmd = proc.spawn('cmd'); 

     //console.log(cmd?'CMD started':'CMD not started'); 

     if (cmd.stdout) { 
     //console.log('stdout present'); 
     cmd.stdout.on('data',function(data) { 
      if (data) { 
      //console.log("data: "+data); 
      socket.emit('cmd', ""+data); 
      } 
     }); 
     } 
     if (cmd.stderr) { 
     cmd.stderr.on('data', function(data) { 
      //console.log('stderr present'); 
      if (data) { 
      socket.emit('cmd', ""+data); 
      } 
     }); 
     } 

     cmd.on('exit', function() { 
     //console.log('cmd exited'); 
     socket.emit('cmd', '[CMD Shutdown]'); 
     if (cmd) { 
      cmd.kill(); 
      cmd = null; 
     } 
     }); 
    } 

    socket.on('sendCmd', function(data) { 
     if (data && data.buffer) { 
     var kB = data.buffer.replace("\r","\n"); 
     if (cmd && cmd.stdin) { 
      cmd.stdin.write(kB); 
     } 
     } 
    }); 

    socket.on('disconnect', function() { 
     console.log('connection closed'); 
     if (cmd) { 
     cmd.stdin.end(); //.kill(); 
     if (cmd) { 
      cmd.kill(); 
      cmd = null; 
     } 
     } 
    }); 
    }); 

编辑:其实,这是一个工作示例的一部分。它缺少捕获并将键击发送到服务器的客户端。但是,它应该给你一个总的想法。