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