2013-10-24 16 views
16

Czytałem o symulacji Linuksa Fabrice'a Bellarda w przeglądarce.Symulowanie terminalu linuksowego w przeglądarce

How does Linux emulator in Javascript by Fabrice Bellard work?

Dzisiaj natknąłem się na tej stronie, gdzie są symulującą pełny terminalu linux w przeglądarce, jestem w stanie uruchomić Python, Perl itd. Wiem, że są uruchomione ich strony na node.js, ale Nie mogłem zrozumieć, jak dokładnie symulują terminal.

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

+3

poprzez prośbę ajax ... spróbuj otworzyć stronę webową firefox i możesz zobaczyć serię zapytań ajaxowych :-) – Hellgorithm

Odpowiedz

21

Pełne Linux jest http://docker.io, reszta jest https://github.com/Runnable/dockworker

Nie jesteśmy symulowanie terminal ale jak mówi Kyle, replikacji terminal nad WebSocket (z ajax zastępczą).

W przeglądarce używamy https://github.com/chjj/term.js pochodzącej z emulatora Fabrice'a Bellarda. Obsługuje wyjście, a także przechwytywanie za naciśnięciem klawisza.

+0

perfect .. Szukałem czegoś takiego. – DevC

+2

Mam uproszczoną wersję obsługującą warsztaty nodeschool.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

To pytanie pochodzi sprzed 4 lat, ale próbuję to zrobić i utknąłem ... Ktoś ma pomysł, jak to zrobić umieścić terminal Docker w aplikacji Meteor? Założyłem https://github.com/mafintosh/docker-browser-console, ale nie mogę sprawić, żeby to działało. Będę wdzięczny za każdą pomoc – Jerome

4

Pozwól poprzedzić to mówiąc, to nie jest dobry pomysł, aby to zrobić.

Ale, możesz odrodzić powłokę i użyć gniazd internetowych lub XMLHttpRequests, aby wcisnąć klawisze do procesu odradzonego serwera. Oto działający przykład takiego, który działa w systemie Windows. Niestety nie udało mi się podłączyć do Ctrl + C. Ale powinieneś to zrozumieć.

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; 
     } 
     } 
    }); 
    }); 

Edycja: Właściwie jest to część działającego przykładu. Brakuje strony klienta, gdzie przechwytywanie i wysyłanie naciśnięć klawiszy na serwerze. Ale powinien dać ci ogólny pomysł.