基于express和socket.io實(shí)現(xiàn)的簡(jiǎn)單聊天室

最近在學(xué)nodejs的時(shí)候允华,自己結(jié)合所學(xué)的知識(shí)運(yùn)用了nodejs的框架express和socket.io實(shí)現(xiàn)了下面簡(jiǎn)單的聊天室

先看一下測(cè)試的截圖:

服務(wù)器端.PNG

git bash下輸入node app.js建立起服務(wù)器

瀏覽器端.PNG

然后再瀏覽器上輸入localhost:3000地址兰粉,輸入名字之后就能進(jìn)入聊天室子寓。

html代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>chat-room</title>
    <link rel="stylesheet" type="text/css" href="css/main.css">
    <script src="javascripts/jquery.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>
    <script src="javascripts/chat.js"></script>
</head>
<body>
  <div class="contaniner">
      <h1>Socket.io - Simple chat room</h1>
      <div class="onlinepeople">
      </div>
      <div id="content"></div>
      <div class="input">
        <span id="status">Connecting...</span>
        <input type="text" id="input" />
      </div>
  </div>
</body>
</html>

css代碼:

* {padding:0px; margin:0px;}
body{font-family:tahoma; font-size:12px;margin:10px;}
p {line-height:18px;padding:2px;}
div {width:500px;}
.contaniner{
    width:600px;
    height:600px;
    border:1px solid #888;
    margin:0 auto;
}
.contaniner h1{
    text-align: center;
}
#content {
    overflow: scroll;
    width:80%;
    margin:0 auto;
    height:70%;
    padding:5px;
    background:#ddd;
    border-radius:5px;
    border:1px solid #CCC;
    margin-top:10px;
}
.input{
    padding-left:50px;
    height:10%;
    width:100%;
    margin:0 auto;
}
#input {
    border-radius:2px;
    border:1px solid #ccc;
    margin-top:10px;
    padding:5px;
    width:380px;
}
#status {
    text-align: center;
    width:100px;
    display:block;
    float:left;
    margin-top:15px;
}

服務(wù)器端:

/**
 * Created by 佳銳 on 2017/3/10.
 */
//使用express快速搭建web服務(wù)器
var express = require('express');
var path = require('path');
var app = express();
var server = require('http').createServer(app);
//使用socket.io監(jiān)聽(tīng)事件
var io = require('socket.io').listen(server);

//對(duì)express配置時(shí)岛啸,從express3遷移到4的一些改變
var favicon = require('serve-favicon');
var logger = require('morgan');
var bodyParser = require('body-parser');
var multer = require('multer');
var methodOverride = require('method-override');
var errorHandler = require('errorhandler');

//設(shè)置日志級(jí)別
io.set('log level',1);
//在線人數(shù)
var onlineCount = 0;
//歷史信息容器
var historyContent = [];

//socket監(jiān)聽(tīng)連接事件
io.on('connection',function(socket){
    socket.emit('onlinepeople',onlineCount);
    socket.emit('historyContentDisplay',historyContent);
    onlineCount++;
    socket.emit('open');//通知客戶(hù)端已連接
    //打印握手信息
    //console.log(socket.handshake);

    //構(gòu)造客戶(hù)端對(duì)象
    var client = {
        socket:socket,
        name:false,
        color:getColor()
    }

    //對(duì)message事件的監(jiān)聽(tīng)
    socket.on('message',function(msg){
        //console.log("111");
        var obj = {
            time:getTime(),
            color:client.color
        };
        //判斷是不是第一次連接庶弃,以第一條信息作為用戶(hù)名
        if(!client.name){
            client.name = msg;
            obj['text']=client.name;
            obj['author']='System';
            obj['type']='welcome';
            console.log(client.name+'login');

            //返回歡迎語(yǔ)
            //觸發(fā)事件痛侍,返回給客戶(hù)端
            socket.emit('system',obj);
            //廣播新用戶(hù)登錄
            socket.broadcast.emit('system',obj);
            //觸發(fā)客戶(hù)端的onlinepeople事件
            socket.emit('onlinepeople',onlineCount);
        }else{
            //如果不是第一次的連接蚜枢,正常的聊天消息
            obj['text']=msg;
            obj['author']=client.name;
            obj['type']='message';
            console.log(client.name+'say:'+msg);
            //返回消息
            //觸發(fā)事件
            socket.emit('message',obj);
            //廣播向其他用戶(hù)發(fā)消息
            socket.broadcast.emit('message',obj);
        }
        //console.log(client.name);
        console.log("在線人數(shù):"+onlineCount);
        historyContent.push({
           'author':obj['author'],
            'time':obj['time'],
            'msg':msg,
            'type':obj['type']
        });
        console.log(historyContent);
    });
    //監(jiān)聽(tīng)退出事件
    socket.on('disconnect',function(){
        onlineCount--;
       var obj = {
         time:getTime(),
           color:client.color,
           author:'System',
           text:client.name,
           type:'disconnect'
       };
        historyContent.push({
            'author':obj['author'],
            'time':obj['time'],
            'msg':obj['text'],
            'type':obj['type']
        });

       //廣播用戶(hù)已退出
        socket.broadcast.emit('system',obj);
        console.log(client.name+'Disconnect');
    });
});
//express基本配置
app.set('port',process.env.PORT || 3000);
app.set('views',__dirname+'/views');
// app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser());
app.use(methodOverride());
//使用express發(fā)送css js等靜態(tài)資源
app.use(express.static(path.join(__dirname, 'public')));

if ('development' == app.get('env')) {
    app.use(errorHandler());
}

//指定websocket的客戶(hù)端的html文件
//express獲得get請(qǐng)求時(shí)將chat.html文件返回給瀏覽器
app.get('/',function(req,res){
    res.sendfile('views/chat.html');
});
//服務(wù)器監(jiān)聽(tīng)端口
server.listen(app.get('port'), function(){
    console.log("Express server listening on port " + app.get('port'));
});

var getTime=function() {
    var date = new Date();
    return date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
};

var getColor=function(){
    var colors = ['aliceblue','antiquewhite','aqua','aquamarine','pink','red','green',
        'orange','blue','blueviolet','brown','burlywood','cadetblue'];
    return colors[Math.round(Math.random() * 10000 % colors.length)];
};

首先使用express快速搭建web服務(wù)器

var express = require('express');
var path = require('path');
var app = express();
var server = require('http').createServer(app);

然后使用socket.io監(jiān)聽(tīng)服務(wù)器

var io = require('socket.io').listen(server);

進(jìn)行express的配置過(guò)程中皆刺,因?yàn)槲业陌姹臼莈xpress3妇蛀,最新版本是express4耕突,所以需要做一定的遷移步驟,具體如下

var favicon = require('serve-favicon');
var logger = require('morgan');
var bodyParser = require('body-parser');
var multer = require('multer');
var methodOverride = require('method-override');
var errorHandler = require('errorhandler');
app.set('port',process.env.PORT || 3000);
app.set('views',__dirname+'/views');
// app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser());
app.use(methodOverride());
//使用express發(fā)送css js等靜態(tài)資源
app.use(express.static(path.join(__dirname, 'public')));

if ('development' == app.get('env')) {
    app.use(errorHandler());
}

socket監(jiān)聽(tīng)連接事件


客戶(hù)端代碼:

/**
 * Created by 佳銳 on 2017/3/10.
 */
$(function(){
    var content = $('#content');
    var status = $('#status');
    var input = $('#input');
    var online = $('.onlinepeople');
    var myName = false;

    //建立websocket連接
    socket = io.connect('http://localhost:3000');
    //收到server的連接確認(rèn)
    socket.on('open',function(){
        status.text('Choose a name:');
    });

    //監(jiān)聽(tīng)system事件评架,判斷welcome或者disconnect,打印系統(tǒng)消息信息
    socket.on('system',function(json){
        var p = '';
        if (json.type === 'welcome'){
            if(myName == json.text) status.text(myName + ': ').css('color', json.color);
            p = '<p style="background:'+json.color+'">system @ '+ json.time+ ' : Welcome ' + json.text +'</p>';
        }else if(json.type == 'disconnect'){
            p = '<p style="background:'+json.color+'">system @ '+ json.time+ ' : Bye ' + json.text +'</p>';
        }
        content.prepend(p);
    });

    socket.on('onlinepeople',function(onlineCount){
           online.text('');
            var  p = '<h2 style="margin-left:50px;">在線人數(shù):'+onlineCount+'</h2>';
            online.prepend(p);
    });

    socket.on('historyContentDisplay',function(historyConten){
        if(historyConten.length != 0) {
            for (var i = 0; i < historyConten.length; i++) {
                if(historyConten[i].type == 'welcome'){
                    var p = '<p><span style="color:'+historyConten[i].color+';">' + historyConten[i].author+'</span> @ '+ historyConten[i].time+ ' : Welcome '+historyConten[i].msg+'</p>';
                    content.prepend(p);
                } else if(historyConten[i].type == 'disconnect'){
                    var p = '<p><span style="color:'+historyConten[i].color+';">' + historyConten[i].author+'</span> @ '+ historyConten[i].time+ ' : Bye'+historyConten[i].msg+'</p>';
                    content.prepend(p);
                } else{
                    var p = '<p><span style="color:'+historyConten[i].color+';">' + historyConten[i].author+'</span> @ '+ historyConten[i].time+ ' : '+historyConten[i].msg+'</p>';
                    content.prepend(p);
                }
            }
            return;
        } else{
            return;
        }
    });
    //發(fā)送事件到服務(wù)端
    //監(jiān)聽(tīng)message事件眷茁,打印消息信息
    socket.on('message',function(json){
        var p = '<p><span style="color:'+json.color+';">' + json.author+'</span> @ '+ json.time+ ' : '+json.text+'</p>';
        content.prepend(p);
    });

    //通過(guò)“回車(chē)”提交聊天信息
    input.keydown(function(e){
        if(e.keyCode == 13){
            var msg = $(this).val();
            if(!msg){
                return;
            }
            socket.send(msg);//將msg發(fā)送到服務(wù)器端
            $(this).val('');
            if(myName === false){
                myName = msg;
            }
        }
    });
});

代碼的地址:https://github.com/McRayFE/chat-room

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市纵诞,隨后出現(xiàn)的幾起案子上祈,更是在濱河造成了極大的恐慌,老刑警劉巖浙芙,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件登刺,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡嗡呼,警方通過(guò)查閱死者的電腦和手機(jī)纸俭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)南窗,“玉大人揍很,你說(shuō)我怎么就攤上這事郎楼。” “怎么了窒悔?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵呜袁,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我简珠,道長(zhǎng)阶界,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任聋庵,我火速辦了婚禮荐操,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘珍策。我一直安慰自己,他們只是感情好宅倒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布攘宙。 她就那樣靜靜地躺著,像睡著了一般拐迁。 火紅的嫁衣襯著肌膚如雪蹭劈。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,598評(píng)論 1 305
  • 那天线召,我揣著相機(jī)與錄音铺韧,去河邊找鬼。 笑死缓淹,一個(gè)胖子當(dāng)著我的面吹牛哈打,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播讯壶,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼料仗,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了伏蚊?” 一聲冷哼從身側(cè)響起立轧,我...
    開(kāi)封第一講書(shū)人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎躏吊,沒(méi)想到半個(gè)月后氛改,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡比伏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年胜卤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赁项。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瑰艘,死狀恐怖是鬼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情紫新,我是刑警寧澤均蜜,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站芒率,受9級(jí)特大地震影響囤耳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜偶芍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一充择、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧匪蟀,春花似錦椎麦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至段化,卻和暖如春嘁捷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背显熏。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工雄嚣, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人喘蟆。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓缓升,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蕴轨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子仔沿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容