(記錄學習中遇到的問題,以及實現的思路,作個備忘吧)css
1、安裝配置html
1.nodejs(傳送門)點這裏html5
二、安裝express,我是安裝的3版本,按住shift鍵而後鼠標右擊,出現下圖node
而後在出現的cmd命令行中輸入 npm install express@3 --save-dev (@3是版本,--save是項目安裝,安裝好了會在項目中的node_modules中找到)jquery
因爲4.x版本中將命令工具單獨分出來了(https://github.com/expressjs/generator),全部要先按裝express-generator,不然建立項目時,會提示express命令沒找到,具體解決辦法請百度git
三、安裝socket.iogithub
在本身的項目目錄運行(同上)輸入 npm install socket.io --save web
由於客戶端也須要引入socket.io因此我在node_modules中找到了socket.io-client文件夾下的socket.io.js,而且複製到了js文件夾中,以便於引用。ajax
如下爲詳細項目目錄express
基本就是這樣了,如今開始寫代碼
2、代碼編寫
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'></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
*{ 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
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
window.onload=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地址:還沒弄。
博客新人,若是有錯,但願告知,謝謝。