docker-browser-server

该项目主要使用了普通的http和websocket,下面从http以及websocket两个方面来说一下遇到的坑。

http

我们的需求主要有如下
1)如何对http请求加过滤器(比如在处理用户权限问题上)

然后websocket

websocket的需求主要有如下
1)docker服务器如何与浏览器进行通信
2)对docker服务器进行操作

下面我分别诉说一下如何做到这几点

1)http过滤器

在index.js文件之中过滤器相当于找到如下代码
 

server.all('uri1',function(req, res, next) {
    //做你想做的内容
    console.log('1')
    next()//表示进入到下一个处理
})

server.all('uri1',function(req, res, next) {
    //做你想做的内容
    console.log('2')
    next()//表示进入到下一个处理
})
  这里面解释如下:   1\. all方法表示处理所有的url为uri1的http请求(包含get,post等方法),如果你只想处理get方法,那么你可以使用  
server.get('uri1',function(req, res, next) {
    //做你想做的内容
    next()//表示进入到下一个处理
})
  2.处理的顺序是和申明的顺序一致的   ### 2)websocket #### 2.1服务器端与浏览器通信 通过websocket进行通信,服务端代码为  
  var wss = new WebSocketServer({server:server})
  var containers = {}

  wss.on('connection', function(connection) {
    var req = connection.upgradeReq
  })
  wss就是一个声明好了的websocket服务器,  
wss.on('connection',function(connection){

})
  这段代码表示ws服务器一旦监听到有客户端连接的事件发生,那么就会执行后面那个函数,入参connection是一个websocket的连接实例,每一个客户端都和服务器有这么一个连接,如果服务器想向客户端发送消息只需要connection.send(.....)就好了。   然后服务端与浏览器具体怎通信呢? 由于我们是web terminal,主要的目的就是如下 把容器里的标准输出流定位到浏览器里,把浏览器上的标准输入流定位到容器中 作者有一个开源项目叫做pump,来实现这个功能 用法很简单,如下  
var pump = require('pump');
var fs = require('fs');

var source = fs.createReadStream('/dev/random');
var dest = fs.createWriteStream('/dev/null');

pump(source, dest, function(err) {
    console.log('pipe finished', err);
});
  这上面的代码就是重定向流的代码,把/dev/random里的东西读入,然后放入到/dev/null中,pump的优势在于如果有一方断开了,那么这个管道就自动删除掉了。   pump更加赞的还有管道连接  
pump(source, transform, anotherTransform, dest, function(err) {
    console.log('pipe finished', err);
});
  这段代码的意思是把source输入到transform中,然后把transform流输入到anotherTransform里面,   查看index.js的代码有这么一段  
                    pump(stream, docker(image, dopts), stream, function(err) {
                        console.log('error in create docker');
                        console.log(err);
                        if (proxy) proxy.close()
                        server.emit('kill', container)
                        delete containers[id]
                    })
    stream就是服务器端和浏览器建立的连接的管道, docker(image.dopts)创建了个服务器与docker服务器之间的管道 这里的意思就是stream的输出定位到服务器与的docker服务器建立的管道中,然后又把这个管道里面的流定位到stream的输入里来,这样就完成了浏览器与docker容器的交互 #### 2.2对docker服务器进行操作 目前只有create镜像,attach镜像,pull镜像三个功能,都在docker_run这个模块中实现。 现在我以pull镜像为例子,在docker-run里面代码如下
  var pull = function(cb){
      console.log('pull image')

      debug('pulling to stdio for %s', image)
      request.post('/images/create?fromImage='+image, {
      }, function(err, response) {
           //处理docker服务器返回的数据
      })
  }
 使用方法如下
pull(function(xx){
     //处理回调
})
 那么在哪儿调用呢?

比如我有一个api是只pull镜像的
/image/{userid}/pull/{imagename}
 那么我就要在docker-browser-server里面增加一个url处理的函数来处理这个api
  server.get('/image{userid}/pull/{imagename}',function(req,res){
        var id = req.params.userid
        var image = req.params.imagename
        var container = containers.hasOwnProperty(id) && containers[id]
        if (container){
             //只让正在使用终端的用户进行pull代码
            container.docker_run.pull(image)
        }
    })
 pull的代码该怎么写呢?在docker-run的index.js中如下
that.pull = function(image){
// pull image
}
好了,我们的代码将完了

docker-browser-server的代码这么执行 
git clone https://github.com/royzhao/docker-browser-server.git
cd docker-browser-server
npm install
cd node_modules
rm -rf docker-browser-console
git clone https://github.com/royzhao/docker-browser-console.git
cd docker-browser-console
npm install
cd node_modules
rm -rf docker-run
git clone https://github.com/royzhao/docker-run.git
cd docker-run
npm install