上一篇node.js环境配置

查看一下node.js和npm(模块管理)版本号

node -v
v0.12.0
npm -v
2.5.1

先运行个小例子

进入示例根目录,如/data/www/hello
新建helloworld.js文件,内容为:

console.log("Hello World");

通过 node命令来执行

node helloworld.js

程序执行后,正常的话,就会在终端输出 Hello World。

Hello World

测试成功后,可删除该文件

接下来

构建基础的 HTTP 服务器

引用教程http://www.w3cschool.cc/nodejs/nodejs-http-server.html

如果我们使用PHP来编写后端的代码时,需要Apache 或者 Nginx 的HTTP 服务器,并配上 mod_php5模块和php-cgi。 从这个角度看,整个"接收 HTTP 请求并提供 Web 页面"的需求根本不需 要 PHP 来处理。 不过对Node.js 来说,概念完全不一样了。使用 Node.js 时,我们不仅仅 在实现一个应用,同时还实现了整个 HTTP服务器。事实上,我们的 Web 应用以及对应的 Web 服务器基本上是一样的。

创建server.js文件,内容如下

var http = require('http');
http.createServer(function (request, response) {
  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.end('Hello World\n');
}).listen(8888);
console.log('Server running at http://127.0.0.1:8888/');

以上代码我们完成了一个可以工作的 HTTP 服务器。
使用 node命令 执行以上的代码:

node server.js
Server running at http://127.0.0.1:8888/

打开浏览器访问 http://127.0.0.1:8888/,你会看到一个写着 "Hello World"的网页,如不是本地环境127.0.0.1改为你的服务器IP

分析Node.js的HTTP服务器:第一行请求(require)Node.js自带的http模块,并且把它赋值给http变量。 接下来我们调用 http 模块提供的函数: createServer 。这个函数会返回 一个对象,这个对象有一个叫做 listen的方法,这个方法有一个数值参数, 指定这个 HTTP 服务器监听的端口号。

socket.io安装

npm install socket.io

用npm ls列出安装的package,看看socket.io是不是安装成功了
由于没有把socket.io加入package.json里的dependencies,npm ls报npm ERR! extraneous 的错误
将socket.io加入package.json的dependencies,如下:

"dependencies": {
    "body-parser": "~1.12.0",
    "cookie-parser": "~1.3.4",
    "debug": "~2.1.1",
    "express": "~4.12.2",
    "jade": "~1.9.2",
    "morgan": "~1.5.1",
    "serve-favicon": "~2.2.0",
    "socket.io": "~1.3.5"
  }

socket.io初体验

来自http://www.open-open.com/lib/view/open1337216216557.html

新建服务端server.js

var fs = require('fs')
    , http = require('http')
    , socketio = require('socket.io');
  
var server = http.createServer(function(req, res) {
    res.writeHead(200, { 'Content-type': 'text/html'});
    res.end(fs.readFileSync(__dirname + '/index.html'));
}).listen(8080, function() {
    console.log('Listening at: http://localhost:8080');
});
  
socketio.listen(server).on('connection', function (socket) {
    socket.on('message', function (msg) {
        console.log('Message Received: ', msg);
        socket.broadcast.emit('message', msg);
    });
});

上述代码是一个超级简单的聊天服务器的实现,该服务器发送 index.html 并侦听所有 WebSockets 请求,通过message事件接收消息,收到格式如下的信息

{"name":"message","args":["hi"]}

则通过socket.broadcast.emit将此信息广播到所有socket端,如此实现了最简单的聊天室功能。
index.html则是通过send方法提交消息,也是通过message事件接收消息,代码如下

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>
    <script>
        $(function(){
            var iosocket = io.connect('http://localhost:8080/');
  
            iosocket.on('connect', function () {
                $('#incomingChatMessages').append($('<li>Connected</li>'));
  
                iosocket.on('message', function(message) {
                    $('#incomingChatMessages').append($('<li></li>').text(message));
                });
                iosocket.on('disconnect', function() {
                    $('#incomingChatMessages').append('<li>Disconnected</li>');
                });
            });
  
            $('#outgoingChatMessage').keypress(function(event) {
                if(event.which == 13) {
                    event.preventDefault();
                    iosocket.send($('#outgoingChatMessage').val());
                    $('#incomingChatMessages').append($('<li></li>').text($('#outgoingChatMessage').val()));
                    $('#outgoingChatMessage').val('');
                }
            });

            $('#submit_btn').click(function() {
                iosocket.send($('#outgoingChatMessage').val());
                $('#incomingChatMessages').append($('<li></li>').text($('#outgoingChatMessage').val()));
                $('#outgoingChatMessage').val('');
            });
            
        });
    </script>
</head>
<body>
Incoming Chat:&nbsp;<ul id="incomingChatMessages"></ul>
<br />
<input type="text" id="outgoingChatMessage"><input type="button" name="submit_btn" id="submit_btn" value="发言">
</body>
</html>

运行server.js文件

node server.js

接下来打开两个浏览器,必须得是支持 WebSockets 的浏览器,例如 Chrome 或者 Safari,访问 http://localhost:8080/ 地址开始互聊。


Express 是一个简洁、灵活的 node.js Web 应用开发框架, 它提供一系列强大的特性,帮助你创建各种 Web 和移动设备应用。
下面我们通过Express4.x运行上面的例子。

Express4.x 安装

npm install -g express

如果是express 4.0之前版本,那么执行“express -V”就可以得到版本号了,可express 4.0之后还需要再安装express-generator包,如果没有安装还执行“express -V”命令会报错。

express4.0之后把创建一个APP的功能分离出来为express-generator,没它你创建不了应用程序

npm install -g express-generator

安装方法参考http://www.cnblogs.com/dacheng/p/nodejs.html

express -v
4.12.1

进入/data/www

express juneng
cd juneng

juneng是安装的文件夹名

npm install
npm start

这里需要注意 express 4.x 无法以 node app.js 为启动方式,而是用指令 npm start 作为启动
访问 http://localhost:3000/ 出现熟悉的Welcome to Express,证明安装成功。

修改bin/www文件

/**
 * Create HTTP server.
 */

//var server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces.
 */
//server.listen(port);
//server.on('error', onError);
//server.on('listening', onListening);

修改后:

var server = app.listen(app.get('port'), function() {
  console.log('Express server listening on port ' + server.address().port);
});

require('../juneng_server').listen(server);

然后在根目录编写juneng_server.js文件:

var io = require('socket.io')();

io.on('connection', function (_socket) {
    console.log(_socket.id + ': connection');
    _socket.on('message', function (msg) {
        console.log('Message Received: ', msg);
        _socket.broadcast.emit('message', msg);
    });
});

exports.listen = function (_server) {
    return io.listen(_server);
};

修改模板文件,express使用的是jade模板引擎,找到view/layout.jade和view/index.jade,修改成如下
layout.jade

doctype html
html
    head
        title= title
        meta(http-equiv="Content-Type", content="text/html; charset=utf-8")
        link(rel='stylesheet', href='/stylesheets/style.css')
        script(src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js")
        script(src='/socket.io/socket.io.js')
        script.
            $(function(){
                var iosocket = io.connect('http://localhost:3000/');
  
                iosocket.on('connect', function () {
                    $('#incomingChatMessages').append($('<li>Connected</li>'));

                    iosocket.on('message', function(message) {
                        $('#incomingChatMessages').append($('<li></li>').text(message));
                    });
                    iosocket.on('disconnect', function() {
                        $('#incomingChatMessages').append('<li>Disconnected</li>');
                    });
                });
  
                $('#outgoingChatMessage').keypress(function(event) {
                    if(event.which == 13) {
                        event.preventDefault();
                        iosocket.send($('#outgoingChatMessage').val());
                        $('#incomingChatMessages').append($('<li></li>').text($('#outgoingChatMessage').val()));
                        $('#outgoingChatMessage').val('');
                    }
                });

                $('#submit_btn').click(function() {
                    iosocket.send($('#outgoingChatMessage').val());
                    $('#incomingChatMessages').append($('<li></li>').text($('#outgoingChatMessage').val()));
                    $('#outgoingChatMessage').val('');
                });
            
            });
    body
        block content

index.jade

extends layout

block content
    p Incoming Chat:&nbsp;
    ul#incomingChatMessages
    br
    input(
        type='text'
        name='outgoingChatMessage'
        id='outgoingChatMessage')
    input(
        type='button'
        name='submit_btn'
        id='submit_btn'
        value="发言")

注意,jade模板里的缩进可以用2个空格,也可以用tab,但是不能混用,会报错,我用的tab键

Express4结合socket.io部分,参考https://cnodejs.org/topic/53c385a1400ca4581bc0f0e4