鏈€杩戞兂鍋氫竴涓狽ode.js搴旂敤鏉ュ疄鐜版垜瀛﹀埌鐨凬ode.js鎶€鑳姐€傛兂浜嗘兂锛岃繕鏄仛涓亰澶╁皬搴旂敤銆傛亹鎬曞悗鏈熺簿鍔涗笉澶熷啓鍗氬涔嬬被鐨勪簡銆傦紙涔嬪墠鍋歱hper鐨勬椂鍊欙紝鍥犱负鎯崇殑鍔熻兘瓒婃潵瓒婂锛屽崐閫旇€屽簾浜嗐€傦級鍥犱负涔嬪墠娌℃湁鍋氳繃WebSocket鐩稿叧鐨勪笟鍔★紝鎵€浠ヤ篃鎯冲湪杩欐柟闈㈣繘琛屽疄璺点€傛湡鏈涚殑鏄仛涓€浜涘崟鑱婂拰缇よ亰锛岀畝鍗曠殑鏈嬪弸鍦堢瓑灏忓姛鑳姐€傚悓鏃讹紝鍥犱负涔嬪墠娌℃湁鐢ㄨ繃mongo锛屾墍浠ヤ篃鎯冲湪杩欐柟闈㈣繘琛屽疄璺点€傛€讳箣锛岃繖涓皬搴旂敤涓昏鏄Node鈥滃叏鏍堚€濈殑鍒濇娴嬭瘯锛屽垎浜粰鍍忔垜涓€鏍疯繕鍦ㄥ洖鑿滅殑鍓嶇銆傚墠鏈熼渶瑕佸疄鐜扮殑鍔熻兘娉ㄥ唽&鐧诲綍蹇呴』閫氱煡褰撳墠鐢ㄦ埛鍦ㄧ嚎/绂荤嚎淇℃伅缁欒嚜宸卞拰鍏朵粬鐢ㄦ埛鍖哄垎瀹㈡埛绔殑娑堟伅绫诲瀷锛屽湪绾夸俊鎭紝娑堟伅绛夊悜鐩爣鐢ㄦ埛鍙戦€佹秷鎭垵姝ュ疄鐜颁箣闂寸殑瀵硅瘽涓や釜鐢ㄦ埛鏆備笖鍋囪鏈夆€嬧€嬬敤鎴穟ser1鍜寀ser2銆傚疄鐜拌繖涓や釜鐢ㄦ埛瀵硅瘽闇€瑕佺殑鎻掍欢鍜屼緷璧杄xpress4.17.1glob7.1.6mongoose5.9.14ejs3.1.2nodemon2.0.4ws7.3.0鍓嶇Websocket閫氫俊瀹炵幇constws=newWebSocket('ws://192.168.31.200:8000')//杩炴帴鍒皐ebsokectserverletuserInfo=JSON.parse(sessionStorage.getItem("userInfo"));//褰撳墠鐢ㄦ埛淇℃伅constJSONToString=function(json){returnJSON.stringify(json)}//杩炴帴鏈嶅姟鍣紝灏嗗綋鍓嶇敤鎴蜂俊鎭彁浜ょ粰鏈嶅姟鍣╳s.onopen=()=>{//ws.send('鎴戝湪绾?),褰撲綘涓婄嚎鏃讹紝鍙渶瑕佸彂閫佸涓嬩俊鎭粰鏈嶅姟鍣ㄥ氨鍩烘湰婊¤冻浜唚s.send(JSON.stringify({sender:userInfo.name}))}//鎺ユ敹娑堟伅fromtheserverws.onmessage=(msg)=>{//鏍规嵁鏈嶅姟鍣ㄨ繑鍥炵殑msg绫诲瀷澶勭悊鐩稿叧閫昏緫锛岄€氱煡鍏朵粬鐢ㄦ埛锛屾覆鏌撴秷鎭瓑//msg.msg绫诲瀷鍒嗕负noticemessage//TODO}//鏈嶅姟鍣ㄩ€氫俊閿欒澶勭悊ws.onerror=err=>{console.log(err)//TODO}//娉ㄩ攢閫昏緫ws.onclose=()=>{ws.send(JSON.stringify({uuid:uuid锛屽彂閫佽€咃細userInfo.name锛屾帴鏀惰€咃細userInfo.name=='user1'?'test2':"user1",message:msg}))console.log('close')}//鍚戞湇鍔″櫒鍙戦€佹秷鎭紝鍏朵粬浜嬩欢璋冪敤璇ユ柟娉昮unctionsendMsgToServer(msg){//msg鏆傚畾鏍煎紡//{//uuid:uuid,//userName:userInfo.name,//receiver:receiver,//message:msg娉ㄦ剰娑堟伅澶氫簬涓婇潰绗竴涓猳nopen//}ws.send(JSONToString(msg))}鏋勫缓expressservice鐩綍缁撴瀯---common|---function.js---db|---mongo.conf.js---routes|---user.js---views|---login.html|----chating.htmlapp.js寮曞叆鍩虹妯″潡骞跺惎鍔ㄦ湇鍔?/app.jsconstexpress=require('express')constapp=express()constglob=require("glob");require('./routes/chats')const{resolve}=require('path');app.listen(3000)console.log('servicestarted')閰嶇疆妯℃澘寮曟搸//app.js/*express.js:閰嶇疆寮曟搸*/app.set('views','./views');//娣诲姞瑙嗗浘璺緞app.engine('html',require('ejs').renderFile);//灏咵JS妯℃澘鏄犲皠鍒扳€?html鈥濇枃浠禷pp.set('viewengine','html');//璁剧疆瑙嗗浘寮曟搸/*express.js:閰嶇疆寮曟搸*/glob.sync(resolve('./views',"**/*.html")).forEach((item,i)=>{lethtmlRelativePath=item.split('/views')[1]letpagePath=htmlRelativePath.replace('.html','')app.get(pagePath,function(request,response){letviewPath=pagePath.replace('/','')response.render(viewPath)})})express瑙f瀽json鏍煎紡鐨勮姹傚弬鏁伴渶瑕佺殑閰嶇疆//app.jsapp.use(express.json())app.use(express.urlencoded({extended:true}))娣诲姞璺敱//app.jsconstuserRouter=require('./routes/user')app.use('/',userRouter)mongo鍩虹閰嶇疆constmongoose=require('mongoose')//寮曞叆mongooseconsturl="mongodb://localhost:27017/chat";//鏈湴鏁版嵁搴撳湴鍧€mongoose.connect(url)constdb=mongoose.connection;db.on('error',console.error.bind(console,'connectionerror:'));db.once('open',function(){console.log("鎴愬姛杩炴帴鍒?+url)});varSchema=mongoose.Schemaletuser={name:String,password:String,headImg:String}varuserSchema=Schema(user)varUser=mongoose.model('鐢ㄦ埛',userSchema);//灏嗘ā寮忕紪璇戝埌妯″瀷鏋勯€犲嚱鏁颁腑module.exports={mongoose,User}//杩欎釜閰嶇疆杩樻槸鏈夌偣绠€闄嬶紝鍚庨潰浼氫慨鏀桂煒ser妯″潡鍔熻兘瀹炵幇//user.jsconstexpress=require('express')constrouter=express.Router()constObjectID=require('mongodb').ObjectID;const{sendJson,throwError}=require('../common/function')const{mongoose,User}=require("../db/mongo.conf")//涓嶈'涓嶅叧蹇冭繖涓洜涓烘鏃舵垜鍙叧娉ㄤ富鍑芥暟馃槑constcheckUserExit=function(params){returnnewPromise(function(resolve,reject){User.findOne(params,function(error,res){if(res){resolve(res)}})})}//娉ㄥ唽router.post('/register',function(request,response){letparams=request.bodyconstuser=newUser(params)checkUserExit({name:params.name}).then(res=>{if(res){response.send(sendJson(0,'鐢ㄦ埛鍚嶅凡缁忓瓨鍦?))}else{user.save(function(error,res){if(閿欒锛墈鍝嶅簲.鍙戦€侊紙throwError锛堬級锛墋else{response.send(sendJson(1,'娉ㄥ唽鎴愬姛'))}})}})})//loginrouter.post('/login',function(request,response){letparams=request.bodyUser.findOne({name:params.name},function(error,res){if(!res){response.send(sendJson(0,'鐢ㄦ埛涓嶅瓨鍦?))}else{if(params.password!=res.password){response.send(sendJson(0,'鐢ㄦ埛鍚嶆垨瀵嗙爜閿欒'))}else{response.send(sendJson(1,'鐢ㄦ埛璁よ瘉鎴愬姛',params))}}})})module.exports=router鐩墠灏佽鐨刾ublic鏂规硶涓嶅锛屼富瑕佹槸瀹炵幇姝e父娴佺▼//function.jsconstgetJsonStr=function(params){returnJSON.stringify(params)}functionsendJson(status,msg,data,params){returngetJsonStr({status:status,message:msg,data:data||null})}functionthrowError(params){returngetJsonStr({status:0,msg:'鏈嶅姟閿欒'})}module.exports.sendJson=sendJsonmodule.exports.throwError=throwErrorWebsocketserver鍩烘湰瀹炵幇姝ラ1.寮€鍚湇鍔onstwebSocket=require('ws');//寮曞叆ws鏈嶅姟鍣ㄦā鍧梒onstws=newwebSocket.Server({port:8000});//鍒涘缓鏈嶅姟鍣紝绔彛涓?000const{JSONToString,getTime}=require('../common/function')varclients={}//璁板綍褰撳墠鍦ㄧ嚎鐢ㄦ埛淇℃伅varuserList=[]//鍙瓨鍌ㄥ綋鍓嶅湪绾跨敤鎴峰悕Step2.杩炴帴鏈嶅姟鍜屽鎴风浜や簰ws.on('connection',(client)=>{//杩炴帴鍒板鎴风//鐢ㄦ埛鍦ㄧ嚎client.on('message',(msg)=>{{letuserMsg=JSON.parse(msg)let{sender,receiver,message}=userMsgclient.name=sender;Observer()//瀹炴椂鏇存柊鍩虹鏁版嵁if(message){//鏁版嵁鍙戦€佽緭鍑簊endMessageToClient(sender,receiver,message)}else{//閫氱煡鍦ㄧ嚎noticeOnlineOrOffLine(sender,true)}})//閿欒淇℃伅client.on('error',(err=>{if(err){console.log(err)//杩樻病鎯冲ソ鎬庝箞鍔瀩}))//绂荤嚎淇℃伅client.on('close',()=>{console.log('user'+client.name+'鍏抽棴娑堟伅鏈嶅姟')noticeOnlineOrOffLine(client.name,false)})})Step3.缁欐寚瀹氱敤鎴峰彂閫佹秷鎭?****@param{*String}sender*@param{*String}receiver*@param{*Object}message*@param{*Boolean}isOnline*/constsendMessageToClient=function(sender,receiver,message){letmessageInfo={sender:sender,message:message,msgType:"message",timestamp:getTime(),userList:userList}//濡傛灉鎺ユ敹鏂瑰湪绾匡紝鍒欏彂閫乮f(receiver){messageInfo.receiver=receiverclients[receiver].send(JSONToString(messageInfo))}clients[sender].send(JSONToString(messageInfo))console.log('鍚戝鎴风鍙戦€佹秷鎭?,JSONToString(messageInfo))}Step4.閫氱煡鍏朵粬鐢ㄦ埛褰撳墠鐢ㄦ埛鍦ㄧ嚎鐘舵€?****@param{*String}currentUser*@param{*Boolean}isOnline*/constnoticeOnlineOrOffLine=function(currentUser,isOnline){for(varkey鍦ㄥ鎴蜂腑锛墈//鍚戜笂/鍚戜笅Line闇€瑕佹洿鏂板叾浠栫敤鎴风殑濂藉弸鍒楄〃})璁﹊sOnlineMsg=isOnline锛?Online':'Offline'console.log('User:'+currentUser+isOnlineMsg+',message:'+JSONToString(noticeUserMessage))clients[key].send(JSONToString(noticeUserMessage))}if(!isOnline){鍒犻櫎瀹㈡埛[褰撳墠鐢ㄦ埛]锛泒}//鍦ㄧ嚎鍜岀绾挎秷鎭ā鏉縞onstonlineOrOffLineNoticeMsg=function(receiver,isOnline){return{receiver:receiver,msgType:'notice',message:isOnline?receiver+'Online':receiver+'offline',timestamp:getTime()}}鑷虫锛岃繖涓皬搴旂敤鐨勪富瑕佸姛鑳藉熀鏈畬鎴愶紝涓囬噷闀垮緛鐨勭涓€姝ワ紝鍝堝搱馃榿锛屽洜涓虹洰鍓嶅畠灏辨槸涓轰簡璁╄亰澶╄繃绋嬭蛋閫氾紝杩炵晫闈㈤兘闅忎究鍐欎簡鍑犱釜div锛堜笉鏄笉鑳界敤锛屾墜鍔ㄧ嫍澶达級銆傚彲鑳藉悇浣嶅瀹樺凡缁忓彂鐜拌亰澶╄繃绋嬩腑涓€鐩存病鏈夌敤鍒癿ongo馃ぃ锛屽洜涓虹洰鍓峬ongo鐨勬縺娲诲Э鍔胯繕涓嶅娣卞叆銆傛€曠粰鑷繁鎸栧潙锛岀瓑杩涗竴姝ヨ鍒掑啀鎼炴暟鎹悗鏈熼渶瑕佸畬鍠勭殑鍔熻兘涓昏鏄兢鑱婏紙閫夋嫨鍥哄畾鐢ㄦ埛鐨勯偅绉嶏紝涓嶆槸澶у鐨勮亰澶╁锛夛紝鍏舵鏄湅鍙嬪湀鍔熻兘鐨勫疄鐜帮紝娑夊強鍒版暟鎹瓨鍌紝鍥剧墖浠ュ強鏂囧瓧澶勭悊绛夛紝闇€瑕佽鍒掑拰瀹屽杽锛屼細杩涗竴姝ユ洿鏂般€傛渶鍚庯紝鐢变簬鏈汉姘村钩鏈夐檺锛屽彲鑳戒娇鐢ㄤ簡姣旇緝鐑傜殑涓氬姟瀹炵幇鏂瑰紡銆傚笇鏈涗笉瑕佽瀵煎垵瀛﹁€呫€傝繕璇峰悇浣嶉珮鎵嬫寚姝c€佸缓璁€佷氦娴併€傞檮涓奼ithub鍦板潃tiny-chat
