Docker语言 — 简单入门

Docker 安装

https://docs.docker.com/engine/installation/

Docker 分两大本子 社区版Community 艾德ition(CE)和专营商版Enterprise
艾德ition(EE)。

CE版本还分稳定版和每月发型版本。 稳定版每季度发型一版。

关于版本号,此前版本例如v1.12 。未来版本直接以发型月份命名,例如v17.09

服务端代码落成

眼下讲到的index.js运维在服务端,之前的代码只是二个简短的WebServer欢迎内容,让大家把WebSocket服务端完整的落到实处代码到场进去,整个服务端就可以拍卖客户端的伸手了。完整的index.js代码如下:

<pre>
var app = require(‘express’)();
var http = require(‘http’).Server(app);
var io = require(‘socket.io’)(http);

app.get(‘/’, function(req, res){
res.send(‘<h1>Welcome Realtime Server</h1>’);
});

//在线用户
var onlineUsers = {};
//当前在线人数
var onlineCount = 0;

io.on(‘connection’, function(socket){
console.log(‘a user connected’);

//监听新用户加入
socket.on('login', function(obj){
    //将新加入用户的唯一标识当作socket的名称,后面退出的时候会用到
    socket.name = obj.userid;

    //检查在线列表,如果不在里面就加入
    if(!onlineUsers.hasOwnProperty(obj.userid)) {
        onlineUsers[obj.userid] = obj.username;
        //在线人数+1
        onlineCount++;
    }

    //向所有客户端广播用户加入
    io.emit('login', {onlineUsers:onlineUsers, onlineCount:onlineCount, user:obj});
    console.log(obj.username+'加入了聊天室');
});

//监听用户退出
socket.on('disconnect', function(){
    //将退出的用户从在线列表中删除
    if(onlineUsers.hasOwnProperty(socket.name)) {
        //退出用户的信息
        var obj = {userid:socket.name, username:onlineUsers[socket.name]};

        //删除
        delete onlineUsers[socket.name];
        //在线人数-1
        onlineCount--;

        //向所有客户端广播用户退出
        io.emit('logout', {onlineUsers:onlineUsers, onlineCount:onlineCount, user:obj});
        console.log(obj.username+'退出了聊天室');
    }
});

//监听用户发布聊天内容
socket.on('message', function(obj){
    //向所有客户端广播发布的消息
    io.emit('message', obj);
    console.log(obj.username+'说:'+obj.content);
});

});

http.listen(3000, function(){
console.log(‘listening on *:3000’);
});
</pre>

翻开全体景况的容器

$ sudo docker ps -a

Socket.IO

Socket.IO是1个开源的WebSocket库,它通过Node.js完成WebSocket服务端,同时也提供客户端JS库。Socket.IO资助以事件为根基的实时双向通信,它可以干活在其他平台、浏览器或活动装备。

Socket.IO支持4种协议:WebSocket、htmlfile、xhr-polling、jsonp-polling,它会活动依照浏览器选用切合的广播发布方式,从而让开发者可以聚焦到功效的落成而不是阳台的包容性,同时Socket.IO具有无可争论的安宁和性质。

常用命令

以下以CentOS 系统为例

搭建WebSocket服务端

其一环节大家尽量的考虑实际生产条件,把WebSocket后端服务搭建成壹个线上可以用域名访问的劳务,尽管您是在本土开发环境,可以换资金地ip地址,只怕利用一个虚拟域名指向当地ip。

先进入到你的劳作目录,比如
/workspace/wwwroot/plhwin/realtime.plhwin.com,新建1个名为
package.json的公文,内容如下:
<pre>
{
“name”: “realtime-server”,
“version”: “0.0.1”,
“description”: “my first realtime server”,
“dependencies”: {}
}
</pre>

接下去使用npm指令安装expresssocket.io
<pre>
npm install –save express
npm install –save socket.io
</pre>
安装成功后,应该可以见到工作目录下生成了2个名为node_modules的公文夹,里面分别是expresssocket.io,接下去可以开头编击败务端的代码了,新建3个文书:index.js

<pre>
var app = require(‘express’)();
var http = require(‘http’).Server(app);
var io = require(‘socket.io’)(http);

app.get(‘/’, function(req, res){
res.send(‘<h1>Welcome Realtime Server</h1>’);
});

http.listen(3000, function(){
console.log(‘listening on *:3000’);
});
</pre>

命令行运营node index.js,倘若一切顺遂,你应当会看出再次来到的listening on *:3000字样,那申明服务业已打响搭建了。此时浏览器中开拓http://localhost:3000有道是能够见到平时的迎接页面。

如若您想要让服务运作在线上服务器,并且可以通过域名访问的话,可以应用Nginx做代理,再nginx.conf中添加如下配置,然后将域名(比如:realtime.plhwin.com)解析到服务器IP即可。
<pre>
server
{
listen 80;
server_name realtime.plhwin.com;
location / {
proxy_pass http://127.0.0.1:3000;
}
}
</pre>

成就上述步骤,http://realtime.plhwin.com:3000的后端服务就不乏先例搭建了。

语言 1

创制并运维容器

$ sudo docker run -d –name xxx -p xxx:xxx imagesName

-d:不打印日志
–name :给容器命名
-p:设置主机端口和照耀端口

安装Node.js

据悉本身的操作系统,去Node.js官网下载安装即可。即使成功安装。在命令行输入node -vnpm -v有道是能来占星应的版本号。

<pre>
node -v
v0.10.26
npm -v
1.4.6
</pre>

查找镜像

$ sudo docker search xxx
用于查找远程仓库中的共享镜像,暗中认同是docker hub

Node.js

Node.js采用C++语言编写而成,它不是Javascript应用,而是二个Javascript的运营环境,据Node.js创办者RyanDahl纪念,他最初梦想拔取Ruby来写Node.js,不过后来发现Ruby虚拟机的属性不或者知足他的渴求,后来他尝试采用V8引擎,所以接纳了C++语言。

Node.js资助的系列包罗*nux、Windows,这象征程序员可以编制系统级只怕服务器端的Javascript代码,交给Node.js来解释施行。Node.js的Web开发框架Express,可以扶持程序员连忙建立web站点,从二零零六年出生于今,Node.js的成材的进程鲜明,其发展前景获得了技能社区的丰裕肯定。

查看镜像

$ sudo docker images

Web领域的实时推送技术,也被称作Realtime技术。这种技能要达标的目标是让用户不必要刷新浏览器就足以博得实时更新。它具备广大的施用场景,比如在线聊天室、在线客服系统、评论系统、WebIM等。

镜像(Image)

看似虚拟机的镜像,镜像是创制Docker容器的基础,用户可以从仓库下载2个曾经做好的采取镜像。
例如二个镜像包涵了全部的Ubuntu操作系统,可以称呼Ubuntu镜像。

专注镜像是只读的

WebSocket简介

谈到Web实时推送,就不得不说WebSocket。在WebSocket出现以前,很多网站为了落到实处实时推送技术,经常接纳的方案是轮询(Polling)和Comet技术,Comet又可划分为二种落成格局,一种是长轮询机制,一种名叫流技术,那两种艺术实际是对轮询技术的修正,这么些方案带来很领会的毛病,必要由浏览器对服务器发出HTTP
request,大批量消耗服务器带宽和财富。面对这种场所,HTML5概念了WebSocket协议,能更好的节约服务器能源和带宽并落到实处真正含义上的实时推送。

WebSocket协议本质上是1个依据TCP的说道,它由通讯协议和编程API组成,WebSocket可以在浏览器和服务器之间建立双向连接,以基于事件的措施,赋予浏览器实时通讯能力。既然是双向通讯,就象击败务器端和客户端可以而且发送并响应请求,而不再像HTTP的伸手和响应。

为了创立一个WebSocket连接,客户端浏览器首先要向服务器发起多少个HTTP请求,这一个请求和平时的HTTP请求例外,包括了一些附加头音信,其中附加头消息”Upgrade:
WebSocket”注脚那是八个提请协议升级的HTTP请求,服务器端解析这几个附加的头新闻然后爆发应答消息再次回到给客户端,客户端和服务器端的WebSocket连接就确立起来了,双方就足以透过那些延续通道自由的传递音信,并且那些连续会不停存在直到客户端依然服务器端的某一方主动的倒闭连接。

二个杰出WebSocket客户端请求头:

语言 2

面前讲到WebSocket是HTML5中新增的一种通讯协议,那意味部分老版本浏览器(重假诺IE10以下版本)并不有所那几个效应,
通过百度计算的公然数据显示,IE8近年来仍以33%的市镇份额占据头名,幸而chrome浏览器市场份额逐年升高,将来以超越26%的市集份额位居第2,同时微软日前公告截止对IE6的技术帮衬并指示用户更新到新本子浏览器,那些早已让很多前端工程师为之头痛的浏览器有望退出历史舞台,再增进大致全数的智能手机浏览器都支持HTML5,所以使得WebSocket的实战意义大增,可是无论怎么着,大家实际上的品类中,依然要考虑低版本浏览器的匹配方案:在支撑WebSocket的浏览器中应用新技巧,而在不帮忙WebSocket的浏览器里启用Comet来收纳发送消息。

启动docker 服务

$ sudo systemctl start docker

编码已毕

先上演示效果图:

语言 3

可以点击那里翻看在线演示。整个开发进程相当简单,上面简单记录了支付步骤:

重启docker服务

$ sudo systemctl restart docker

客户端代码完成

进入客户端工作目录/workspace/wwwroot/plhwin/demo.plhwin.com/chat,新建一个index.html:

<!DOCTYPE html>
<html>
<head>
<meta charset=”utf-8″>
<meta name=”format-detection” content=”telephone=no”/>
<meta name=”format-detection” content=”email=no”/>
<meta content=”width=device-width, initial-scale=1.0,
maximum-scale=1.0, minimum-scale=1.0, user-scalable=0″
name=”viewport”>
<title>五人聊天室</title>
<link rel="stylesheet" type="text/css" href="./style.css" />

<script src="http://realtime.plhwin.com:3000/socket.io/socket.io.js"></script>
</head>
<body>

请先输入你在聊天室的昵称


<script type="text/javascript" src="./client.js"></script>

</html>

地点的html内容小编没有啥好说的,大家根本看看里面的肆个公文请求:

1、realtime.plhwin.com:3000/socket.io/socket.io.js
2、style.css
3、json3.min.js
4、client.js

第三个JS是Socket.IO提供的客户端JS文件,在前边安装服务端的手续中,当npm安装完socket.io并搭建起WebServer后,那几个JS文件就足以健康访问了。

第一个style.css文件没什么好说的,就是样式文件而已。

语言,第二个JS只在IE8以下版本的IE浏览器中加载,目标是让这么些低版本的IE浏览器也能处理json,那是1个开源的JS,详见:http://bestiejs.github.io/json3/

第4个client.js是完整的客户端的工作逻辑达成代码,它的始末如下:

<pre>
(function () {
var d = document,
w = window,
p = parseInt,
dd = d.documentElement,
db = d.body,
dc = d.compatMode == ‘CSS1Compat’,
dx = dc ? dd: db,
ec = encodeURIComponent;

w.CHAT = {
    msgObj:d.getElementById("message"),
    screenheight:w.innerHeight ? w.innerHeight : dx.clientHeight,
    username:null,
    userid:null,
    socket:null,
    //让浏览器滚动条保持在最低部
    scrollToBottom:function(){
        w.scrollTo(0, this.msgObj.clientHeight);
    },
    //退出,本例只是一个简单的刷新
    logout:function(){
        //this.socket.disconnect();
        location.reload();
    },
    //提交聊天消息内容
    submit:function(){
        var content = d.getElementById("content").value;
        if(content != ''){
            var obj = {
                userid: this.userid,
                username: this.username,
                content: content
            };
            this.socket.emit('message', obj);
            d.getElementById("content").value = '';
        }
        return false;
    },
    genUid:function(){
        return new Date().getTime()+""+Math.floor(Math.random()*899+100);
    },
    //更新系统消息,本例中在用户加入、退出的时候调用
    updateSysMsg:function(o, action){
        //当前在线用户列表
        var onlineUsers = o.onlineUsers;
        //当前在线人数
        var onlineCount = o.onlineCount;
        //新加入用户的信息
        var user = o.user;

        //更新在线人数
        var userhtml = '';
        var separator = '';
        for(key in onlineUsers) {
            if(onlineUsers.hasOwnProperty(key)){
                userhtml += separator+onlineUsers[key];
                separator = '、';
            }
        }
        d.getElementById("onlinecount").innerHTML = '当前共有 '+onlineCount+' 人在线,在线列表:'+userhtml;

        //添加系统消息
        var html = '';
        html += '<div class="msg-system">';
        html += user.username;
        html += (action == 'login') ? ' 加入了聊天室' : ' 退出了聊天室';
        html += '</div>';
        var section = d.createElement('section');
        section.className = 'system J-mjrlinkWrap J-cutMsg';
        section.innerHTML = html;
        this.msgObj.appendChild(section);   
        this.scrollToBottom();
    },
    //第一个界面用户提交用户名
    usernameSubmit:function(){
        var username = d.getElementById("username").value;
        if(username != ""){
            d.getElementById("username").value = '';
            d.getElementById("loginbox").style.display = 'none';
            d.getElementById("chatbox").style.display = 'block';
            this.init(username);
        }
        return false;
    },
    init:function(username){
        //客户端根据时间和随机数生成uid,这样使得聊天室用户名称可以重复。实际项目中,如果是需要用户登录,那么直接采用用户的uid来做标识就可以
        this.userid = this.genUid();
        this.username = username;

        d.getElementById("showusername").innerHTML = this.username;
        this.msgObj.style.minHeight = (this.screenheight - db.clientHeight + this.msgObj.clientHeight) + "px";
        this.scrollToBottom();

        //连接websocket后端服务器
        this.socket = io.connect('ws://realtime.plhwin.com:3000');

        //告诉服务器端有用户登录
        this.socket.emit('login', {userid:this.userid, username:this.username});

        //监听新用户登录
        this.socket.on('login', function(o){
            CHAT.updateSysMsg(o, 'login');  
        });

        //监听用户退出
        this.socket.on('logout', function(o){
            CHAT.updateSysMsg(o, 'logout');
        });

        //监听消息发送
        this.socket.on('message', function(obj){
            var isme = (obj.userid == CHAT.userid) ? true : false;
            var contentDiv = '<div>'+obj.content+'</div>';
            var usernameDiv = ''+obj.username+'';

            var section = d.createElement('section');
            if(isme){
                section.className = 'user';
                section.innerHTML = contentDiv + usernameDiv;
            } else {
                section.className = 'service';
                section.innerHTML = usernameDiv + contentDiv;
            }
            CHAT.msgObj.appendChild(section);
            CHAT.scrollToBottom();  
        });

    }
};
//通过“回车”提交用户名
d.getElementById("username").onkeydown = function(e) {
    e = e || event;
    if (e.keyCode === 13) {
        CHAT.usernameSubmit();
    }
};
//通过“回车”提交信息
d.getElementById("content").onkeydown = function(e) {
    e = e || event;
    if (e.keyCode === 13) {
        CHAT.submit();
    }
};

})();
</pre>

由来所有的编码开发工作总体完了了,在浏览器中打开http://demo.plhwin.com/chat/就可以见见功效了,后续小编会把演示代码提交到Github上。

本例只是二个简便的德姆o,留下二个关于项目扩展的思考:

壹,假设是一个在线客服系统,里面有那一个的店堂使用你的劳动,各个公司温馨的用户可以透过三个附属UHighlanderL地址进入该商行的聊天室,聊天是一对一的,每一个公司得以新建多少个客服人士,每一个客服人士可以而且和客户端的多少个用户聊天。

2、又如果是二个在线WebIM系统,落成类似微信,qq的效应,客户端可以见见好友在线状态,在线列表,添加好友,删除好友,新建群组等,新闻的出殡除了辅助宗旨的文字外,还可以支持表情、图片和文书。

有趣味的同校可以继承深切钻研。

容器(Container)

容器类似于3个沙箱,Docker
利用容器来运作和隔离应用。可以领略成1个集装箱。

WebSocket实战

本文将以几人在线聊天应用作为实例场景,大家先来规定这些聊天应用的中坚需要。

上传镜像到私人仓库

  1. 登录仓库:
    $ docker login xx.xx.xx.xx

  2. 标记Images
    $ docker tag friendlyhello xx.xx.xx.xx/firstimage/friendlyhello

  3. 上传:
    $docker push xx.xx.xx.xx/项目/IMAGE[:TAG]

急需分析

一,兼容不襄助WebSocket的低版本浏览器。
二,允许客户端有一样的用户名。
三,进入聊天室后得以看看日前在线的用户和在线人数。
四,用户上线或剥离,全体在线的客户端应该实时更新。
伍,用户发送消息,全数客户端实时收取。

在实质上的费用进程中,为了利用WebSocket接口营造Web应用,大家先是要求打造壹个落实了
WebSocket规范的服务端,服务端的已毕不受平台和付出语言的范围,只必要听从WebSocket规范即可,如今一度面世了一些相比成熟的WebSocket服务端落成,比如本文使用的Node.js+Socket.IO。为什么采纳那几个方案吗?先来回顾介绍下他们两。

什么是Docker

仓库(Repository)

仓库类似于大家存放代码的仓库,就是Docker二种存放镜像的地方。
官方仓库:Docker store。也可以协调搭建私人仓库,例如Harbor。

登录仓库

$ sudo docker login

地处已有个别镜像的器皿创制

$ docker commit -m “注释” -a “小编” -p 容器ID 新镜像名
-p 表示提交暂停容器运营

翻开docker运营处境

$ sudo systemctl status docker

剔除镜像

$ sudo docker rmi xxxx
xxx 可以为标签也足以为ID

删去容器

$ sudo docker rm imagesid

查阅运转中的容器

$ sudo docker ps

核心概念

  1. 镜像(Image)
  2. 容器(Container)
  3. 仓库(Repository)

翻看docker 详细消息

$ sudo docker info

处在本地模板导入

$ sudo cat ubuntu-14.04-x86-minimal.tar.gz | docker import -ubuntu:14.04

居于Dockerfile创建

https://docs.docker.com/get-started/part2/

开机自动运营docker服务

$ sudo systemctl enable docker

始建镜像并上传私人仓:

创设镜像有三种艺术:

  1. 据悉已某个镜像的器皿创造
  2. 依据本地模板导入
  3. 基于Dockerfile创建

报到私人仓库:

$ sudo docker login host

关闭docker服务

$ sudo systemctl stop docker

Rancher 介绍

官方文档:https://rancher.com/docs/rancher/v1.6/zh/

翻开某镜像详细音信

$ sudo docker inspect xxxx
xxxx 代表 image id

收获镜像

$ sudo docker pull xxx
xxx 代表镜像名

容器(沙盒)

基于Liunx的容器技术,Docker进一步优化容器。
让使用运营在容器中,不一样的容器彼此隔离又有啥不可成立通讯机制。
容器本人对轻易的须求很低,远低于现在的虚拟机。

开源

出生于二〇一三年头,基于Go语言的开源项目。

Harbor 介绍

GitHub地址:https://github.com/vmware/harbor
搭建进度:http://www.jianshu.com/p/7218e66440f9

终止容器

$ sudo docker stop imagesid

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图