Nodejs搭建简易聊天室

使用Node.js搭建简易聊天室

功能概述:

可以模拟聊天室,每个人自定义用户名和消息,在“首页”发表“评论”。

但是,并没有实现数据持久化(没用数据库),只是一个简单的案例

使用到:Bootstrap、art-template模板引擎。


目录

功能概述:

1.核心源码  app.js:

2.视图 

3.效果图:

4.源码下载


1.核心源码  app.js:

var http = require('http');
var fs = require('fs');
var url = require('url');
var template = require('art-template');

//模拟5条数据
var comments = [
    {
        name: 'Node',
        message: 'Hello Node.js',
        dateTime: '2018年08月02日 09:01:50'
    },
    {
        name: 'Node2',
        message: 'Hello Node.js',
        dateTime: '2018年08月02日 09:01:50'
    },
    {
        name: 'Node3',
        message: 'Hello Node.js',
        dateTime: '2018年08月02日 09:01:50'
    },
    {
        name: 'Node4',
        message: 'Hello Node.js',
        dateTime: '2018年08月02日 09:01:50'
    },
    {
        name: 'Node5',
        message: 'Hello Node.js',
        dateTime: '2018年08月02日 09:01:50'
    }
];

// 对于这种表单提交的请求路径,由于其中具有用户动态填写的内容
// 所以你不可能通过去判断完整的 url 路径来处理这个请求
http
    .createServer(function (req, res) {
        // 使用 url.parse 方法将路径解析为一个方便操作的对象,
        // 第二个参数为 true 表示直接将查询字符串转为一个对象(通过 query 属性来访问)
        var parseObj = url.parse(req.url, true);

        // 单独获取不包含查询字符串的路径部分(该路径不包含 ? 之后的内容)
        // 例如 /pinglun?name=Node&message=helloNode
        //调用下面的方法,返回 /pinglun
        var pathname = parseObj.pathname;

        if (pathname === '/') {
            fs.readFile('./views/index.html', function (err, data) {
                if (err) {
                    return res.end('404 Not Found.')
                }
                //渲染数据
                var htmlStr = template.render(data.toString(), {
                    comments: comments
                });
                res.end(htmlStr)
            })
        } else if (pathname === '/post') {
            // 其它的都处理成 404 找不到
            fs.readFile('./views/post.html', function (err, data) {
                if (err) {
                    return res.end('404 Not Found.');
                }
                res.end(data);
            })
        } else if (pathname.indexOf('/public/') === 0) {
            // /public/js/main.js
            // /public/lib/jquery.js
            // 统一处理:
            //    如果请求路径是以 /public/ 开头的,则我认为你要获取 public 中的某个资源
            //    所以我们就直接可以把请求路径当作文件路径来直接进行读取
            fs.readFile('.' + pathname, function (err, data) {
                if (err) {
                    return res.end('404 Not Found.');
                }
                res.end(data)
            })
        } else if (pathname === '/pinglun') {
            // 注意:这个时候无论 /pinglun?xxx 之后是什么,我都不用担心了,因为我的 pathname 是不包含 ? 之后的那个路径
            // 我们已经使用 url 模块的 parse 方法把请求路径中的查询字符串给解析成一个对象了

            //1. 获取表单提交的数据 parseObj.query
            var comment = parseObj.query;
            //2. 将当前时间日期添加到数据对象中
            comment.dateTime = getNowTime();
            //3.存储到数组中,unshift为存在数组头
            comments.unshift(comment);
            //服务端这个时候已经把数据存储好了,接下来就是让用户重新请求 / 首页,就可以看到最新的留言内容了
            //4. 让用户重定向跳转到首页 /
            //5. 状态码设置为 302 临时重定向
            res.statusCode = 302;
            //6. 在响应头中通过 Location 告诉客户端往哪儿重定向
            res.setHeader('Location', '/');
            // 如果客户端发现收到服务器的响应的状态码是 302 就会自动去响应头中找 Location ,然后对该地址发起新的请求
            // 所以客户端自动跳转了
            //当用户重新请求 / 的时候,我数组中的数据已经发生变化了,所以用户看到的页面也就变了
            res.end()
        } else {
            // 其它的都处理成 404 找不到
            fs.readFile('./views/404.html', function (err, data) {
                if (err) {
                    return res.end('404 Not Found.');
                }
                res.end(data);
            })
        }
    })
    .listen(8888, function () {
        console.log('running...');
    })

//获取当前时间方法
function getNowTime() {
    var date = new Date();
    var year = date.getFullYear();
    var month = date.getMonth()+1;
    var day = date.getDate();
    var hour = date.getHours();
    var minute = date.getMinutes();
    var second = date.getSeconds();
    var myTime = (year+'年'+(month>9?month:'0'+month)
        +'月'+(day>9?day:'0'+day)+'日 '
        +(hour>9?hour:'0'+hour)+':'
        +(minute>9?minute:'0'+minute)
        +':'+(second>9?second:'0'+second));
    return myTime;
}

2.视图 

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>留言本</title>
    <link rel="stylesheet" href="/public/css/bootstrap.css">
</head>

<body>
<div class="header container">
    <div class="page-header">
        <h1>首页
            <small>Node聊天室</small>
        </h1>
        <a class="btn btn-success" href="/post">发表留言</a>
    </div>
</div>
<div class="comments container">
    <ul class="list-group">
        {{each comments}}
        <li class="list-group-item">{{ $value.name }}说:{{ $value.message }} <span class="pull-right">{{ $value.dateTime }}</span>
        </li>
        {{/each}}
    </ul>
</div>
</body>

</html>

post.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="/public/css/bootstrap.css">
</head>

<body>
<div class="header container">
    <div class="page-header">
        <h1><a href="/">首页</a>
            <small>发表评论</small>
        </h1>
    </div>
</div>
<div class="comments container">
    <form action="/pinglun" method="get">
        <div class="form-group">
            <label for="input_name">你的大名</label>
            <input type="text" class="form-control" required minlength="2" maxlength="10" id="input_name" name="name"
                   placeholder="请写入你的姓名">
        </div>
        <div class="form-group">
            <label for="textarea_message">留言内容</label>
            <textarea class="form-control" name="message" id="textarea_message" cols="30" rows="10" required
                      minlength="5" maxlength="20"></textarea>
        </div>
        <button type="submit" class="btn btn-default">发表</button>
    </form>
</div>
</body>

</html>

3.效果图:

     首页:


    评论页:

4.源码下载

https://download.csdn.net/download/litongzero/10578414

猜你喜欢

转载自blog.csdn.net/LitongZero/article/details/81352384