该项目主要使用了普通的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