利用socket.io+nodejs打造简单聊天室

demo获取:

demo地址
下载后再package.json所在位置打开命令行,通过npm install安装依赖,安装好后通过node app.js 启动服务,在google浏览器中输入 localhost:3000

界面展示:

首先展示demo的结果界面,只是简单消息的发送和接收,包括发送文字和发送图片。




ws说明:

在介绍socket.io之前,先简单介绍一下websocket:

Web Socket的目标是在一个单独的持久连接上提供全双工,双向通信

在JavaScript中建立了Web Socket之后,会有一个HTTP请求发送到浏览器以发送连接。取得服务器响应之后,建立的连接会使用HTTP升级从HTTP协议交换为WebSocket协议。WebSocket使用了自定义的协议,所以URL模式略有不同,未加密的是ws://,加密的是wss://,使用WebSocket的好处在于:可以在客户端和服务器端发送少量数据,减少开销,且由于全双工通信,适合即时应用。但是目前还达不到浏览器完全兼容。

Socket.IO

Socket.IO官网
官网列出了Socket.IO的四大优点:

  • 实时分析:将数据推送到客户端,这些客户端会被表示为实时计数器,图表或日志客户。
  • 实时通信和聊天:只需几行代码便可写成一个Socket.IO的”Hello,World”聊天应用。
  • 二进制流传输:从1.0版本开始,Socket.IO支持任何形式的二进制文件传输,例如:图片,视频,音频等。
  • 文档合并:允许多个用户同时编辑一个文档,并且能够看到每个用户做出的修改。
    Socket.IO对于支持ws的浏览器将采用ws通信,对于不支持ws的将采用轮询方式,所以Socket.IO是一个非常适合做即时通讯的类库。

Socket.IO API

由于Socket.IO在不同版本中,API会略有不同,所以本文介绍依赖于1.4.5版本(2016.9.8)
官网对于API及用法介绍全面,在此只做简单总结:

  • 1、安装:npm install socket.io
  • 2、客户端:客户端需引用socket.io.js
<script src="/javascripts/socket.io.js"></script>
<script>var socket = io.connect();</script>
  • 3、服务器端:demo中服务器端采用框架express(~4.13.1),将引用模块命名为io
//引入模块
var server = app.listen(3000,function(){
          console.log('Express.js server listening on port'+ app.get('port'));});
var io = require('socket.io').listen(server);
//io使用
io.on('connection', function (socket) {})
  • 4、服务器端API
io.on('connection',function(socket){});//建立连接
io.sockets.emit(约定参数,data);//向全体人员广播
io.emit(约定参数, data);//向全体人员广播
socket.emit(约定参数,data)//发送信息
socket.on(约定参数,callback);//接收信息
socket.on('disconnect',callback);//用户断开连接触发事件

Socket.IO对于每一个连接用户会自动分配一个随机的,不重复的Socket#id ,通过Socket#id可以实现将信息分发给个人

var socketId = socket.id;
socket.broadcast.to(socketId ).emit('my message', msg);//socket均为connect中回调函数中的socket
  • 5、客户端API
socket.emit(约定参数,data)//发送信息
socket.on(约定参数,callback);//接收信息

Demo介绍

package.json

{
  "name": "ezsocket",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "body-parser": "~1.13.2",
    "cookie-parser": "~1.3.5",
    "debug": "~2.2.0",
    "express": "~4.13.1",
    "jade": "~1.11.0",
    "morgan": "~1.6.1",
    "multiparty":"4.1.2",
    "socket.io":"1.4.5",
    "serve-favicon": "~2.3.0"
  }
}

框架及版本如上,视图采用jade模板,主要过程为用户进入聊天室先输入名字(未查重),点击确定后发送名字等信息,进入聊天页面,在文本框中输入,点击发送按钮,发送信息。接收服务器端的相应信息,对其处理,进行界面的展示。

$(function(){
    var socket=io.connect();
    $('.j_btn').on('click',function(){//进入页面确定按钮点击事件
        console.log(8888);
        var msg = $('.j_nametext').val();
        socket.emit('login',msg);//向服务器发送用户注册名字信息
    })
    $('#j_mesbtn').on('click',function(){//文本框按钮点击事件
        var data = $('#j_msgtext').html();
        console.log(data);
        var str = '<li><div class="top-right-content"><pre>'+data+'</pre></div></li>'
        $('.right-top-ul').append(str);
        socket.emit('msg',data);//向服务器发送文本框中信息
    })
    socket.on('system',function(data){//接收服务器端信息
        var str = '<li class="right-top-time" style="color:red">欢迎  '+data+'  进入聊天室,撒花</li>';
        $('.right-top-ul').append(str);
    });
    socket.on('chat',function(data){
        console.log(data);
        var str = '<li><div class="top-left-content"><span>'+data.name+'</span><pre>'+data.data+'</pre></div></li>'
        $('.right-top-ul').append(str);
    })
    socket.on('loginSuccess',function(){//接收服务器端登录成功信息
        $('.float-player').css('display','none');
        $('.dialog').css('display','none');
    });
    socket.on('disconnect',function(data){//接收服务器端发送的用户离开的信息
        console.log(data);
        var str = '<li class="right-top-time" style="color:red">  '+data+'  离开了组织,愿他早日回到组织的怀抱</li>';
        $('.right-top-ul').append(str);
    });
    $('#j_sendmsg').on('change',function(){//上传文件事件
        // 判断上传文件类型
        var objFile = $('#j_sendmsg').val();
        var objType = objFile.substring(objFile.lastIndexOf(".")).toLowerCase();
        var formData = new FormData(document.forms.namedItem("test"));
        $.ajax({
            type : 'post',
            url : '/uploadUserImgPre',
            data: formData ,
            processData:false,
            async:false,
            cache: false,  
            contentType: false, 
            success:function(re){
                re.imgSrc = re.imgSrc.replace('public','');
                re.imgSrc = re.imgSrc.replace(/\\/g,'\/');
                $('#j_msgtext').append('[站外图片上传中……(4)]')
            },
            error:function(re){
                console.log(re);
            }
        }); 
    });
})

服务器端主要功能为
1、前方发送登录信息,服务器端接收并广播给全部用户,将登录成功信息传给客户端,客户端进行相应操作。
2、客户端通过发送按钮发送信息,服务器端收到后,广播给除非发送人员所有人。
3、用户离开,触发服务器端disconnect,服武器端广播给全体在线人员。
代码如下:

io.on('connection', function(socket) {  
  console.log(socket.id);
  var socketId = socket.id;
  socket.on('login',function(nickname){//接收登录
    socket.nickname = nickname; 
    socket.emit('loginSuccess');//发送登录成功信息
    io.sockets.emit('system', nickname);//广播
  });
  socket.on('msg',function(data){//接收文本框中信息
    console.log(data);
    var sendMsg = {'name':socket.nickname,'data':data}
    socket.broadcast.emit('chat',sendMsg);//广播
  });
  socket.on('disconnect',function(){
    io.sockets.emit('disconnect', socket.nickname);
  })
});

总结:

本文对Socket.IO做了简单了解,若有不足或错误之处,还请多多指出。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容