(记录学习中遇到的问题,以及实现的思路,做个备忘吧)
一、安装配置
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
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
<!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'></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'></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'></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">×</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>
index.css
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
*{ 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%; }
app.js
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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() }
socketTest.js
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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--------*/ };
GitHub地址:还没弄。
博客新人,如果有错,希望告知,谢谢。