CentOS7源码安装node.js和webSocket

来源:互联网 发布:问卷调查数据分析方法 编辑:程序博客网 时间:2024/05/19 12:38

CentOS7源码安装node.js和webSocket

学习参考:http://ourjs.com/detail/529ca5950cb6498814000005

 

如果iptables是开启的,要先加入80端口和socket监听端口(可以自己设置)

官网:https://nodejs.org

下载页面:https://nodejs.org/download/release/

中文手册:http://nodeapi.ucdok.com/#/api/

# yum -y installgcc gcc-c++ openssl-devel  libssl-dev (如果是安装到32位系统需要再安装:yum install glibc.i686  zlib.i686

我在编译安装node时出现下面错误,解决办法:

# yum whatprovides libstdc++.so.6          //找到对于依赖的包,然后安装

# cd/data/software && wget -c https://nodejs.org/download/release/latest-v9.x/node-v9.0.0-linux-x86.tar.gz&& tar -zxvf node-v9.0.0-linux-x86.tar.gz  && cd  node-v9.0.0-linux-x86/bin  && ./node

 

出现上图说明nodejs安装成功了

# cp /data/software/node-v9.0.0-linux-x86/bin/*  /usr/sbin/ && node -v

# cd/data/software/node-v9.0.0-linux-x86/lib/node_modules/npm &&./configure  && make &&make install

修改npm的命令文件中的basedir路径,否则执行npm命令时老是报错

# cd /usr/lib/node_modules/npm/bin&&  vi npm

basedir="/usr/lib"

# cp/usr/lib/node_modules/npm/bin/npm /usr/sbin/npm  && npm -v

上图说明npm安装成功

使用npm命令安装express和socket.io  如果只是临时安装 Express,不想将它添加到依赖列表中,只需略去 --save 参数即可,安装 Node 模块时,如果指定了 --save 参数,那么此模块将被添加到 package.json 文件中 dependencies 依赖列表中。 然后通过 npm install 命令即可自动安装依赖列表中所列出的所有模块。

如果安装上面内容出错时,则给npm初始化,生成一个package.json文件:

# mkdir -p /data/software/node_modules  && cd /data/software/node_modules&& npm init

下面红色标记的要手动输入:

最后生成下面红色标记文件:

# cd /usr/lib/node_modules&& npm install --save express &&  npm install --savesocket.io  && ls

如上图红色标记,说明安装成功

建立网站根目录:

# mkdir /dataweb/www&& cd /dataweb/www && mkdir nodejs   //作为nodejs存放服务器端的js目录,要和网页根目录分开,而且不能通过url地址访问的到

把express 和 socket.io 拷贝过来,因为server.js要引用:

# cp -r  /data/software/node_modules/socket.io/  nodejs/

# cp -r  /data/software/node_modules/express/  nodejs/

# cd nodejs

# viserver.js   //作为webSocket服务器端

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 RealtimeServer</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');

});

 

# node index.js

 

建立客户端的js文件:

# vi client.js

(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 += '<divclass="msg-system">';

            html += user.username;

            html += (action == 'login') ? ' 加入了聊天室' : ' 退出了聊天室';

            html += '</div>';

            var section =d.createElement('section');

            section.className = 'systemJ-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://192.168.12.180: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 ='<span>'+obj.username+'</span>';

 

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

        }

    };

})();

 

把下面的js代码拷贝到本地,用于兼容IE8以下浏览器能够解析json格式字符串

http://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js

 

去https://socket.io 找到最新版本的socket.io.js 然后拷贝到 /data/software/www/目录下面用于调用(或者去:/data/software/node_modules/socket.io/node_modules/socket.io-client/socket.io.js找)

# find / -name socket.io.js

# cp /data/software/node_modules/socket.io/node_modules/socket.io-client/socket.io.js  /data/software/www/

# cd /data/software/www

建立用于客户端聊天的网页

# vi  index.html

<!DOCTYPEhtml>

<html>

    <head>

        <meta charset="utf-8">

        <metaname="format-detection" content="telephone=no"/>

        <metaname="format-detection" content="email=no"/>

<metacontent="width=device-width, initial-scale=1.0, maximum-scale=1.0,minimum-scale=1.0, user-scalable=0" name="viewport">

        <title>多人聊天室</title>

        <!--[if lt IE 8]><scriptsrc="./json3.min.js"></script><![endif]-->

        <scriptsrc="./socket.io.js"></script>

    </head>

    <body>

        <div id="loginbox">

            <divstyle="width:260px;margin:200px auto;">

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

                <br/>

                <br/>

                <input type="text"style="width:180px;" placeholder="请输入用户名" id="username"name="username" />

                <inputtype="button" style="width:50px;" value="提交"onclick="CHAT.usernameSubmit();"/>

            </div>

        </div>

        <div id="chatbox"style="display:none;">

            <divstyle="background:#3d3d3d;height: 28px; width:100%;font-size:12px;">

                <divstyle="line-height: 28px;color:#fff;">

                    <spanstyle="text-align:left;margin-left:10px;">Websocket多人聊天室</span>

                    <spanstyle="float:right; margin-right:10px;"><spanid="showusername"></span> |

                    <ahref="javascript:;" onclick="CHAT.logout()"style="color:#fff;">退出</a></span>

                </div>

            </div>

            <div id="doc">

                <div id="chat">

                    <divid="message" class="message">

<divid="onlinecount" style="background:#EFEFF4; font-size:12px;margin-top:10px; margin-left:10px; color:#666;">

</div>

                    </div>

                    <divclass="input-box">

                        <divclass="input">

<inputtype="text" maxlength="140" placeholder="请输入聊天内容,按Ctrl提交" id="content"name="content">

                        </div>

                        <divclass="action">

                            <buttontype="button" id="mjr_send"onclick="CHAT.submit();">提交</button>

                        </div>

                    </div>

                </div>

            </div>

        </div>

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

    </body>

</html>

把刚才几个js文件加载进去:

修改nginx配置文件(前提是已经安装了nginx):

# vi /usr/local/nginx/conf/nginx.conf

然后通过浏览器访问:http://192.168.12.180/

测试环境:访问前先关闭iptables

如下图,说明成功了:

如果firebug出现下面错误,很有可能是服务器端的nodejs(上面的node  index.js)关闭了

把nodejs的模块都安装到下面目录

 # cd  /data/software/node-v0.12.9-linux-x64/bin/node_modules

安装mysql扩展:

# npm install  --save mysql

安装redis扩展:(参考:http://my.oschina.net/robanlee/blog/261720)

# npm install   --save redis

# vi index.js

//连接mysql数据库

var mysql  = require('/data/software/node-v0.12.9-linux-x64/bin/node_modules/mysql');

var conn =mysql.createConnection({   

       host    : '127.0.0.1',

       user    : 'test_user',

       password : '888888',

       port    : 3306,

       database : 'test'

});

conn.connect();

conn.query('select* from `cmge_account`', function(err, rows, fields) {

    if (err) throw err;

    console.log('The solution is: ', rows);

});

conn.end();

 

 

//调用redis模块

var redis =require("/data/software/node-v0.12.9-linux-x64/bin/node_modules/redis");

var client =redis.createClient(6379,'127.0.0.1',{connect_timeout:1}); //增加超时选项

//console.log(client);

client.info(function(err,response){

      // console.log(err,response);

});

//get & set

client.set('roban','this is an testing val', function(err, response) {

    if (err) {

        console.log('Failed to set key ofroban, error:' + err);

        return false;

    }

 

   client.get('roban',function(errGet,responseGet){

        console.log('Val:'+responseGet);

    });

 

});

 

在开发Node.js 实现的HTTP 应用时会发现,无论你修改了代码的哪一部份,都必须终止
Node.js 再重新运行才会奏效。这是因为Node.js 只有在第一次引用到某部份时才会去解析脚本文件,以后都会直接访问内存,避免重复载入,而PHP 则总是重新读取并解析脚本(如
果没有专门的优化配置)。Node.js的这种设计虽然有利于提高性能,却不利于开发调试,因
为我们在开发过程中总是希望修改后立即看到效果,而不是每次都要终止进程并重启。
supervisor 可以帮助你实现这个功能,它会监视你对代码的改动,并自动重启Node.js

# npm install -gsupervisor

# supervisor  test_server.js &

让nodejs应用当成服务,在后台执行

# nohup nodeserver.js &

或者安装forever能做更多的事情,比如分别记录输出和错误日志,比如可以在js中作为api使用

# npm installforever -g   #安装

$ forever startapp.js          #启动

$ forever stopapp.js           #关闭

$ forever start -lforever.log -o out.log -e err.log app.js   #输出日志和错误

下面的-w参数是自动监控文件变化,文件修改保存了自动重启test_server.js

# forever -wtest_server.js

 

用脚本判断nodejs进程是否存在,如果不存在则自动启动

# vi node.sh

#!/bin/sh

#监测客服服务器端的进程是否存在,如果不存在则启动

while :

do

sleep 1

RESULT=`ps -e|grep'/usr/bin/supervisor test_server.js'|sed -e "/grep/d"`

if [ -z"$RESULT" ];then #判断RESULT是否为空,为空则说明进程未启动  

      /usr/bin/supervisor test_server.js

fi

done

 

 

#sh node.sh

# crontab -e

0 */2 * * * sh /data/cmge/oss2.cmge.com/nodejs/node.sh

 

如果要用域名访问nodejs做的web网站,需要在nginx的配置文件修改:

 

针对nodejs崩溃自动重启问题,可以参考:https://github.com/Unitech/pm2

# npm install pm2-g        # 安装 PM2

# pm2 start test_server_new.js--watch        # 启动和自动重启node

 

pm2 starttest_server_new.js --watch  --log  ‘/data/log/nodejs/kf2.shengli.com/’

pm2 monit

 

pm2 start  server_new2.js --watch

 

 

Nodejs内存监测:

参考:http://web.jobbole.com/85684/

node--max-old-space-size=512 server_new2.js

说明:--max-old-space-size  限制占用内存大小,单位:M

原创粉丝点击