nodejs+express+socket.io实现多人聊天室

(记录学习中遇到的问题,以及实现的思路,做个备忘吧)

一、安装配置

1.nodejs(传送门)点这里

2、安装express,我是安装的3版本,按住shift键然后鼠标右击,出现下图

然后在出现的cmd命令行中输入 npm install express@3 --save-dev    (@3是版本,--save是项目安装,安装好了会在项目中的node_modules中找到

 

由于4.x版本中将命令工具单独分出来了(https://github.com/expressjs/generator),所有要先按装express-generator,否则创建项目时,会提示express命令没找到,具体解决办法请百度

3、安装socket.io

在自己的项目目录运行(同上)输入 npm install socket.io --save 

因为客户端也需要引入socket.io所以我在node_modules中找到了socket.io-client文件夹下的socket.io.js,并且复制到了js文件夹中,以便于引用。

以下为详细项目目录

基本就是这样了,现在开始写代码

二、代码编写

1.我的思路

这里先记录下我理解的思路,首先浏览器客户端发送A事件,而在服务器端监听A事件,如果服务器监听到A事件,进行逻辑处理,处理完毕后,广播B事件,这里的B事件,会广播到每一个与服务器建立socket链接的客户端。

然后在客户端中监听B事件,然后再做渲染处理。

2.引入文件

在index页面引入jq和socket.io.js,以及自己创建的js文件

<script src='dep/bootstrap-3.3.5/js/jquery-1.11.3.js'></script>
<script src='./js/socket.io.js'></script>
<script src=js/socketTest.js></script>

3.代码编写

  1).socketTest.js

 var socket = io();/*引入socket*/
    $(document).keypress(function (event) {
        if(event.keyCode == 13){
            $('#sendMes').trigger('click')
        }
    });
    $('#mesFrom').submit(function () {
        var someMsg = $('#MessageValue').val();
        nickName || (nickName='匿名'+''+parseInt(Math.random()*10000+1)+'');/*判断用户是否输入用户名,没有则为匿名+1000的随机数*/
        $('.userNickName').html(nickName)
        if ($.trim(someMsg) !== '') {/*判断提交的信息是否为空*/
            socket.emit('chatmessage', {nickName: nickName, Msg: someMsg});/*发布chatmessage事件,并且传递一个对象*/
            $('#MessageValue').val('');
        }
        return false;
    });
    socket.on('message', function (obj) {/*监听服务器发送的message事件*/
        $('#someMessage').append($('<li>').text(obj.name + ':' + '(' + obj.sendMsgTime + ')'));
        $('#someMessage').append($('<span class="msgStyle">'+obj.chatMsg+'</span>'));
        var outinUlHeight=$('#someMessage').height();
        var outsideWrapHeight=$('.messageBox').height();
        $('.messageBox').scrollTop(outinUlHeight-outsideWrapHeight+10);/*让最新的消息显示在底部*/
    });

 

  2).服务器文件,app.js

   

const express = require("express");/*引入express*/
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.configure(function () {
    app.use(express.logger("dev"));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(app.router);
    app.use(express.static(__dirname + "/src/public"));/*设置静态目录,当请求为/的时候,默认为public/index.html文件*/
    app.use(express.errorHandler());
})
var person = {};
var user=[];
var allUserNum=0;
io.on('connection', function (socket) {
    allUserNum++;/*客户端每次建立连接  在线人数+1*/
    socket.on('chatmessage', function (msg) {/*监听客户端发送的chatmessage事件*/
        person.name = msg.nickName;
        person.chatMsg = msg.Msg;
        person.AllPerson = allUserNum;
        var sendMsgTime = getDate();
        person.sendMsgTime = sendMsgTime;
        io.emit('message', person);/*向与服务器建立socket连接的客户端广播message事件*/
    });
});
http.listen(8888, function () {
    console.log('listening on *:8888');
});

function getDate() {
    var Mydate = new Date();
    return Mydate.toLocaleString()
}

以下为详细代码;

index.html

<!doctype html>
<html>
<head>
    <meta name="viewport" content="initial-scale=1, user-scalable=0, minimal-ui">
    <title>Socket.IO chat</title>
    <link rel="stylesheet" href="dep/bootstrap-3.3.5/css/bootstrap.css">
    <link rel="stylesheet" href="dep/iconfont/iconfont.css">
    <link rel="stylesheet" href="css/index.css">
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
    <![endif]-->
    <!--[if IE 7]>
    <script src="js/json2.js"></script>
    <![endif]-->
</head>
<body>
<nav class="navbar navbar-default nav-bar" role="navigation">
    <div class="container-fluid">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse"
                    data-target="#example-navbar-collapse">
                <span class="sr-only">切换导航</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#"><i class='iconfont logo-icon'>&#xe625;</i><span class='icon-title'>WeiChat</span></a>
        </div>
        <div class="collapse navbar-collapse" id="example-navbar-collapse">
            <ul class="nav navbar-nav">
                <li class="active"><a href="#">公共聊天室</a></li>
                <li><a href="#">一对多(客服模式)</a></li>
                <li><a href="#">一对一(私信模式)</a></li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">
                         更多<b class="caret"></b>
                    </a>
                    <ul class="dropdown-menu">
                        <li><a href="#">暂无更多</a></li>
                    </ul>
                </li>
            </ul>
        </div>
    </div>
</nav>
<section class='row' id='chatBox'>
    <div class='chat-content col-lg-offset-4 col-lg-4 col-md-4 col-md-offset-4 col-sm-12' style='padding-left: 0;padding-right: 0'>
        <h4 class='content-title'>
            <span class='content-left-title'>
                <i class='iconfont chatroom-title-icon'>&#xe612;</i><span id='room-title'>公共聊天室</span>
            </span>
            <span class='content-right-title'>
                <div id="userInfo-wrap"><span class="userNickName"></span><i class='glyphicon glyphicon-user padding10'></i></div>
                <div id="userNum-wrap"><span class="allUserInline">当前在线:<span id="allInline"></span></span><i class='glyphicon glyphicon-ok-sign inline-color padding101'></i></div>
            </span>
        </h4>
        <div class='messageBox'>
            <ul id='someMessage'>
                <!--这是聊天记录显示区域-->
            </ul>
        </div>
        <div class='sendmessageBox'>
            <div class='chatFun'>
                <span><i class='iconfont someImg'>&#xe62c;</i></span>
            </div>
            <form action="##" id='mesFrom'>
                <textarea name="" id='MessageValue' style='white-space: pre;resize: none;' ></textarea>
                <div class=btn-positoin><button id='sendMes'>发送 <span class='glyphicon glyphicon-triangle-bottom'></span> </button></div>
            </form>
        </div>
    </div>
</section>
<!--模态框-->
<div class="modal fade filter" tabindex="-1" role="dialog" aria-labelledby="gridSystemModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="gridSystemModalLabel"> 取个昵称吧</h4>
            </div>
            <div class="modal-body">
                <div class="row">
                    <div class='nickName-wrap'>
                        <div class=input-wrap>
                            <input type="text" id='nickNameInput'><button class=' btn-sm random-btn'>随机</button>
                            <span id='usernameInfo'></span>
                        </div>
                    </div>
                </div>
            </div>
            <div class="modal-footer">
                <!--<button type="button" class="btn btn-default" data-dismiss="modal">不取</button>-->
                <button type="button" class="enter-inputName  btn">就这个</button>
            </div>
        </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<button style='display: none' type="button" id='nickNameModal' class=" btn-lg" data-toggle="modal" data-target=".modal"></button>
</body>
<script src='dep/bootstrap-3.3.5/js/jquery-1.11.3.js'></script>
<script src='dep/bootstrap-3.3.5/js/bootstrap.min.js'></script>
<script src=js/socketTest.js></script>
<script src='./js/socket.io.js'></script>
</html>
View Code

index.css

    *{
        margin: 0;
        padding: 0;
        font-family: 'Microsoft Ya Hei';
    }
    html{
        font-size: 62.5%;
    }
    /*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
    /*::-webkit-scrollbar*/
    /*{*/
        /*width: 5px;*/
        /*height: 5px;*/
        /*background-color: #F5F5F5;*/
    /*}*/

    /*!*定义滚动条轨道 内阴影+圆角*!*/
    /*::-webkit-scrollbar-track*/
    /*{*/
        /*-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);*/
        /*border-radius: 10px;*/
        /*background-color: #F5F5F5;*/
    /*}*/

    /*!*定义滑块 内阴影+圆角*!*/
    /*::-webkit-scrollbar-thumb*/
    /*{*/
        /*border-radius: 10px;*/
        /*-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);*/
        /*background-color: #45cd94;*/
    /*}*/
    #chatBox{
        margin: 0 auto;
        /*height: 500px;*/
        background-color: white;
        /*outline: 1px solid red;*/
    }
    .chat-content{
        border: 1px solid rgba(157, 157, 157, 0.56);
        border-radius: 5px;
        padding-bottom: 5px;
        height: 460px;
    }
    .title{
        text-align: center;
        color: #fff;
        font-size: 4rem;
        background-color: rgba(0, 0, 0, 0.51);
    }
    .content-title{
        height: 60px;
        line-height: 60px;
        margin: 0;
        padding-left: 3% ;
        border-top:5px solid #3fc18e;
        border-top-left-radius: 5px;
        border-top-right-radius: 5px;
        background-color: #eee;
    }
    .messageBox{
        height: 250px;
        overflow-y: scroll;
        /*outline: 1px solid black;*/
    }
    .msgStyle{
        position: relative;
        left: 15px;
        top:0;
        padding: 6px 9px;
        max-width: 45%;
        line-height: 1.4rem;
        display: inline-block;
        background-color: #eee;
        border-radius: 2px;
    }
    .msgStyle:after{
        content: '';
    }
    .sendmessageBox{
        height: 100px;
        border-top: 1px solid #eee;
    }
    .chatFun{
        margin: 0 1% 0 1%;
        height: 35%;
        width: 98%;
        padding-top: 1%;
        cursor: pointer;
        /*vertical-align: middle;*/
        /*outline: 1px solid black;*/
    }
    .someImg{
        font-size: 1.9rem;
    }
    #mesFrom{
        height: 150px;
        /*outline: 1px solid gold;*/
    }
    #MessageValue{
        text-align:left;
        border-bottom-left-radius:4px;
        border-bottom-right-radius:4px;
        border:1px solid #c8cccf;
        color:#6a6f77;
        -web-kit-appearance:none;
        -moz-appearance: none;
        display:block;
        outline:0;
        text-decoration:none;
        width:98%;
        margin-left: 1%;
        height: 60px;
        display: inline-block;
        padding-left: 10px;
        font-size: 15px;
    }
    #sendMes{
        margin-right: 1%;
        margin-top: 1%;
        width: 25%;
        height: 30px;
        /*padding: 5px 9px 5px 9px;*/
        color: #fff;
        background-color: #3eb381;
        border: none;
        border-radius: 4px;
        display: inline-block;
    }
    .btn-positoin{
        text-align: right;
    }
    #sendMes:hover{
        cursor: pointer;
        background-color: #34936a;
    }
    .logo-icon{
        font-size: 3rem;
        color: #34936a;
    }
    .chatroom-title-icon{
        color: #999;
        font-size: 1.3rem;
        padding-right: 3%;
    }
    .content-left-title{
        float: left;
        width: 30%;
        height: 55px;
    }
    .content-right-title{
        float: right;
        text-align: right;
        padding-right: 2%;
        width:65%;
        height: 55px;
        line-height: 55px;
        font-size: 1.3rem;
        color: #999;
    }
    #userInfo-wrap{
        width: 45%;
        height: 55px;
        float: left;
    }
    .userNickName{
        text-overflow: ellipsis;
        display: inline-block;
        white-space:nowrap;
        overflow: hidden;
        float: right;
    }
    .allUserInline{
        display: inline-block;
        float: right;
    }
    #userNum-wrap{
        float: right;
        width: 53%;
    }
    .icon-title{
        color: #327951;
    }
    .padding10{
        padding-left: 10px;
        padding-right: 5px;
        line-height: 55px;
        float: right;
    }
    .padding101{
        margin-right: 5px;
        line-height: 55px;
        float: right;
    }
    .inline-color{
        color: #3eb381;
    }
    #someMessage>li{
        padding: 1% 2% 1% 1%;
    }
    .nav-bar{
        margin-bottom: 0;
    }
    #room-title{
        font-size: 1.5rem;
    }
    .nickName-wrap{
        text-align: center;
        padding: 2% 0 2% 0;
    }
    #nickNameInput{
        width: 48%;
        height: 30px;
        max-height: 35px;
        min-height: 25px;
        border:1px solid #e2e2e2;
        padding-left: 2%;
    }
    .input-wrap{
        width: 100%;
        display: inline-block;
        text-align: center;
    }
    .random-btn{
        margin-left: 1%;
        margin-top: -3px;
        background-color: #3eb381;
        border:1px solid #3eb381;
        color:white;
    }
    .enter-inputName{
        width: 100%;
        background-color: #3eb381;
        border:1px solid #3eb381;
        color:white;
    }
    .modal-title{
        color: #777;
        text-align: center;
    }
    #usernameInfo{
        display: block;
        text-align: center;
        color: #a83940;
        font-size: 1rem;
        margin-top: 3%;
    }
View Code

app.js

const express = require("express");/*引入express*/
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.configure(function () {
    app.use(express.logger("dev"));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(app.router);
    app.use(express.static(__dirname + "/src/public"));/*设置静态目录,当请求为/的时候,默认为public/index.html文件*/
    app.use(express.errorHandler());
})
var person = {};
var user=[];
var allUserNum=0;
io.on('connection', function (socket) {
    allUserNum++;/*客户端每次建立连接  在线人数+1*/
    socket.on('chatmessage', function (msg) {/*监听客户端发送的chatmessage事件*/
        person.name = msg.nickName;
        person.chatMsg = msg.Msg;
        person.AllPerson = allUserNum;
        var sendMsgTime = getDate();
        person.sendMsgTime = sendMsgTime;
        io.emit('message', person);/*向与服务器建立socket连接的客户端广播message事件*/
    });
    socket.on('allUser',function (msg) {
      io.emit('allUser',allUserNum)
    })
});
app.get('/searchAllPerson.do',function (req,resp) {
    resp.send(allUserNum)
})
app.get('/searchUserName.do',function (req,resp) {
    resp.send(user)
})
app.post('/userResigte.do',function (req,resp) {
    var name = req.body.username;
    user.push(name);
    resp.send('ok')
})

http.listen(8888, function () {
    console.log('listening on *:8888');
});

function getDate() {
    var Mydate = new Date();
    return Mydate.toLocaleString()
}
View Code

socketTest.js

window.οnlοad=function () {
    /*检测ie版本,暂时不支持ie7,未做ie7兼容处理*/
    var browser=navigator.appName
    var b_version=navigator.appVersion
    var version=b_version.split(";");
    var trim_Version=version[1].replace(/[ ]/g,"");
    if(browser=="Microsoft Internet Explorer" && trim_Version=="MSIE7.0")
    {
        alert("暂时不支持IE 7.0,请更新您的浏览器。");
    }
    var nickName;
    /*用户注册----start-------*/
    $('#nickNameModal').trigger('click');/*页面加载显示模态框*/
    $('.random-btn').click(function () {/*随机选取名字*/
        $(this).val('');
        var adjWord = ['开心的','忧伤的','快乐的','愉快的','难过的','孤单的','无聊的','阳光的','帅气的','英俊的','看起来傻傻的'];
        var nWord = ['馒头','二哈','胡萝卜','猫咪','帅哥','美女','丝瓜','南瓜','冬瓜','哈密瓜','木瓜'];
        var firstName=adjWord[parseInt(Math.random()*10)];
        var lastName=nWord[parseInt(Math.random()*10)];
        $('#nickNameInput').val(firstName+lastName)
    });
    $('.enter-inputName').click(function () {/*提交用户姓名*/
        nickName =$('#nickNameInput').val();
        if(nickName!==''){
            userResig(nickName);
        }else {/*判断是否注册名字,没有就显示匿名+随机码*/
            $('#usernameInfo').html('您的身份将会是’匿名‘');
            nickName='匿名'+''+parseInt(Math.random()*10000+1)+'';
            userResig(nickName)
        }

    });
    function userResig(nickName) {
        $.ajax({
            url:'/userResigte.do',
            type:'post',
            data:'username='+nickName,
            success:function (result) {
                if(result==='ok'){
                    $('.filter').trigger('click')
                    $('.userNickName').html(nickName)
                    $('#MessageValue').focus();
                }
            }
        })
    }
    /*用户注册--------end---------*/

    /*用户发送信息-----start--------*/
    var socket = io();/*引入socket*/
    $(document).keypress(function (event) {
        if(event.keyCode == 13){
            $('#sendMes').trigger('click')
        }
    });
    $('#mesFrom').submit(function () {
        var someMsg = $('#MessageValue').val();
        nickName || (nickName='匿名'+''+parseInt(Math.random()*10000+1)+'');/*判断用户是否输入用户名,没有则为匿名+1000的随机数*/
        $('.userNickName').html(nickName)
        if ($.trim(someMsg) !== '') {/*判断提交的信息是否为空*/
            socket.emit('chatmessage', {nickName: nickName, Msg: someMsg});/*发布chatmessage事件,并且传递一个对象*/
            $('#MessageValue').val('');
        }
        return false;
    });
    socket.on('message', function (obj) {/*监听服务器发送的message事件*/
        $('#someMessage').append($('<li>').text(obj.name + ':' + '(' + obj.sendMsgTime + ')'));
        $('#someMessage').append($('<span class="msgStyle">'+obj.chatMsg+'</span>'));
        var outinUlHeight=$('#someMessage').height();
        var outsideWrapHeight=$('.messageBox').height();
        $('.messageBox').scrollTop(outinUlHeight-outsideWrapHeight+10);/*让最新的消息显示在底部*/
    });
    socket.emit('allUser', {nickName:'s'});
    socket.on('allUser',function (data) {
      $('#allInline').html(data)
    })
    /*用户发送信息-----end--------*/
};
View Code

GitHub地址:还没弄。

博客新人,如果有错,希望告知,谢谢。

转载于:https://www.cnblogs.com/cqkm/p/7124945.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用 Node.js 和 Socket.io 实现多人聊天室的基本步骤: 1. 安装 Node.js 和 Socket.io 首先需要安装 Node.js 和 Socket.io。可以在 Node.js 官网下载并安装 Node.js,然后在命令行中使用以下命令安装 Socket.io: ``` npm install socket.io ``` 2. 创建服务器 创建一个 Node.js 服务器,并在其中引入 Socket.io 模块。创建一个 HTTP 服务器,并使用 Socket.io 将其升级为 WebSocket 服务器。 ```javascript const http = require('http'); const express = require('express'); const socketIO = require('socket.io'); const app = express(); const server = http.createServer(app); const io = socketIO(server); server.listen(3000, () => { console.log('Server listening on port 3000'); }); ``` 3. 监听连接事件 使用 Socket.io 监听 `connection` 事件,当有新的客户端连接到服务器时,触发该事件。 ```javascript io.on('connection', (socket) => { console.log('New client connected'); }); ``` 4. 处理消息事件 在连接事件中,可以监听 `message` 事件,以接收客户端发送的消息。当接收到消息时,将其广播给所有连接到服务器的客户端。 ```javascript io.on('connection', (socket) => { console.log('New client connected'); socket.on('message', (message) => { console.log('Received message: ', message); io.emit('message', message); }); }); ``` 5. 创建客户端 创建一个 HTML 页面作为客户端,使用 Socket.io 连接到服务器,并监听 `message` 事件以接收其他客户端发送的消息。 ```html <!DOCTYPE html> <html> <head> <title>Chat Room</title> <script src="/socket.io/socket.io.js"></script> <script> const socket = io(); socket.on('message', (message) => { const li = document.createElement('li'); li.innerText = message; document.getElementById('messages').appendChild(li); }); function sendMessage() { const input = document.getElementById('messageInput'); socket.emit('message', input.value); input.value = ''; } </script> </head> <body> <ul id="messages"></ul> <input type="text" id="messageInput"> <button onclick="sendMessage()">Send</button> </body> </html> ``` 6. 运行程序 运行 Node.js 服务器,并在浏览器中打开客户端页面。多个客户端连接到服务器后,可以在聊天室中发送消息。 这就是使用 Node.js 和 Socket.io 实现多人聊天室的基本步骤。当然,还可以添加许多其他功能,例如用户身份验证、私人消息等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值