Node.JSの高度なチャット

はい、インターネットには雑然としたチャットの実装がたくさんありますが、それでも私はそれらが好きではありません。 ブラックジャックを使用して、チャットの実装を紹介します。



だから、すぐにせっかちな人のためのデモへのリンク

(サーバーはすでに収納されています)



特徴









仕組み





まあ、すべてが簡単です





方法





依存関係のインストール




sudo yum install nodejs sudo yum install mongodb npm install ws npm install mongodb
      
      







プログラム可能




まず、クライアント部分を作成し、node.jsおよびサーバーに必要な他のものをすべてインストールします。



HTMLは非常に簡潔です



 <!DOCTYPE html> <html> <head> <link href='http://fonts.googleapis.com/css?family=Ubuntu&subset=latin,cyrillic' rel='stylesheet' type='text/css'> <link href="main.css" rel="stylesheet" /> <script src="main.js" defer></script> <meta charset="UTF-8"> </head> <body> <form id="loginform" class="unauthorized"> <input id="login" placeholder=""><br> <input id="password" placeholder=""> <div>*    ,   </div> </form> <output id="messages"></output> <div> <div contenteditable id="input"></div> </div> </body> </html>
      
      







script



タグのdefer



属性のおかげで、javascriptはページ全体をロードした後にのみ開始されます。 これは、 window.onload



イベントよりもはるかに便利です。



コードを減らすには、 document.getElementById



$



に減らしdocument.getElementById







 function $(a){return document.getElementById(a)}
      
      







サーバーへの接続を開き、着信メッセージを待ちます



 ws = new WebSocket ('ws://x.cloudx.cx:9000'); ws.onmessage = function (message) { //        var event = JSON.parse(message.data); //     ,   switch (event.type) { case 'message': //    var name = document.createElement('div'); var icon = document.createElement('div'); var body = document.createElement('div'); var root = document.createElement('div'); name.innerText = event.from; body.innerText = specials_in(event); root.appendChild(name); root.appendChild(icon); root.appendChild(body); $('messages').appendChild (root); break; case 'authorize': //      if (event.success) { $('loginform').classList.remove('unauthorized'); } break; default: //   ,       console.log ('unknown event:', event) break; } }
      
      







着信メッセージが最初にspecials_in



関数によって処理されることに気づいたかもしれません。 この関数は、チャット機能を拡張するメッセージ本文内の特別なフラグメントを検索します。



 function specials_in (event) { var message = event.message; var moment = new Date(event.time); //      var time = (moment.getHours()<10)? '0'+moment.getHours() : moment.getHours(); time = (moment.getMinutes()<10)? time+':0'+moment.getMinutes() : time+':'+moment.getMinutes(); time = (moment.getSeconds()<10)? time+':0'+moment.getSeconds() : time+':'+moment.getSeconds(); var date = (moment.getDate()<10)? '0'+moment.getDate() : moment.getDate(); date = (moment.getMonth()<10)? date+'.0'+moment.getMinutes()+'.'+moment.getFullYear() : date+':'+moment.getMonth()+'.'+moment.getFullYear() message = message.replace(/\[time\]/gim, time); message = message.replace(/\[date\]/gim, date); return message; }
      
      







送信メッセージの同様の機能



 function specials_out(message) { // /me message = message.replace(/\s*\/me\s/, $('login').value+' '); return message; }
      
      







クライアント側の残りのコード、珍しいことは何もありません
 //   Enter     $('password').onkeydown = function (e) { if (e.which == 13) { //    authorize ws.send (JSON.stringify ({ type: 'authorize', user: $('login').value, password: $('password').value })); } } //   Enter     $('input').onkeydown = function (e) { //    Ctrl+Enter  Shift+Enter,     . if (e.which == 13 && !e.ctrlKey && !e.shiftKey) { //    message ws.send (JSON.stringify ({ type: 'message', message: specials_out($('input').innerText) })); $('input').innerText = ''; //    } } //      var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { var objDiv = $('messages'); objDiv.scrollTop = objDiv.scrollHeight; }); }).observe($('messages'), { childList: true });
      
      









サーバー側に行きましょう



データベースに接続し、ポート9000のWebソケットでの接続を待ちます



 //   var WebSocketServer = require('ws').Server, wss = new WebSocketServer({port: 9000}); //    var MongoClient = require('mongodb').MongoClient, format = require('util').format; var userListDB, chatDB; //    MongoClient.connect('mongodb://127.0.0.1:27017', function (err, db) { if (err) {throw err} //     ()    userListDB = db.collection('users'); chatDB = db.collection('chat'); });
      
      







承認と登録は、ユーザーにとって可能な限り簡単に行われます。 アカウントがない場合は、作成されます。



 //         function existUser (user, callback) { userListDB.find({login: user}).toArray(function (error, list) { callback (list.length !== 0); }); } //         function checkUser (user, password, callback) { // ,     existUser(user, function (exist) { //    if (exist) { //        userListDB.find({login: user}).toArray(function (error, list) { //   callback (list.pop().password === password); }); } else { //   ,    userListDB.insert ({login: user, password: password}, {w:1}, function (err) { if (err) {throw err} }); //   ,   callback (true); } }); }
      
      







すべてのチャット参加者にメッセージを送信する

この関数が機能するためには、各参加者との接続へのリンクがpeers



配列にあります



 //     function broadcast (by, message) { //   ,     var time = new Date().getTime(); //     peers.forEach (function (ws) { ws.send (JSON.stringify ({ type: 'message', message: message, from: by, time: time })); }); //     chatDB.insert ({message: message, from: by, time: time}, {w:1}, function (err) { if (err) {throw err} }); }
      
      







新しい接続とメッセージの処理



 //    wss.on('connection', function (ws) { //   var login = ''; var registered = false; //    ws.on('message', function (message) { //      var event = JSON.parse(message); //    ,    if (event.type === 'authorize') { //   checkUser(event.user, event.password, function (success) { //        registered = success; //    var returning = {type:'authorize', success: success}; //  ,  if (success) { //        returning.online = lpeers; //        lpeers.push (event.user); //        peers.push (ws); //        login = event.user; //    ws.on ('close', function () { peers.exterminate(ws); lpeers.exterminate(login); }); } //  , ,   ws.send (JSON.stringify(returning)); //      if (success) { sendNewMessages(ws); } }); } else { //    ,    if (registered) { //    switch (event.type) { //    case 'message': //    broadcast (login, event.message) break; //    ,     case 'type': //     ,      break; } } } }); });
      
      







上記のコードが機能するためには、履歴からメッセージを受信する機能、オンラインの人々のリスト、および配列から要素を削除する機能も必要です。



 //    ( ) var lpeers = []; //        function sendNewMessages (ws) { chatDB.find().toArray(function(error, entries) { if (error) {throw error} entries.forEach(function (entry){ entry.type = 'message'; ws.send (JSON.stringify (entry)); }); }); } //        Array.prototype.exterminate = function (value) { this.splice(this.indexOf(value), 1); }
      
      







チャットの準備ができました!



ソースはここで取得できます

(サーバーは定期的に横たわっています)



走れる



 su - mongod --smallfiles > /dev/null & node path/to/server.js > /dev/null &
      
      







藤堂






All Articles