Node.js、Express、Socket.io 入门

转载 2016年05月30日 18:47:42

http://www.cnblogs.com/sword-successful/p/4987124.html

前言

      周末断断续续的写了第一个socket.io Demo。初次接触socket.io是从其官网看到的,看着get started做了一遍,根据官网的Demo能提供简单的服务端和客户端通讯。 这个Demo的过程中用到最多的就是订阅事件、触发事件、广播事件。

      根据官网完成Demo后,看到下面提到了几个问题,又继续实现了四个功能,其它几个还要继续实现。

      ①、当有新用户登录或离开时广播消息。

      ②、添加昵称。我在demo中的做法是把用户输入的第一条消息作为昵称。

      ③、发送消息时自己发送的消息不再给自己发送,其实也就是只调用广播(socket.broadcast.emit)消息的方法即可。

      ④、显示当前在线用户和在线人数。

开发环境

      node:0.12.7

      express:4.13.7

      socket.io:1.3.7

 

官网Demo中遇到的问题

      ①、客户端html页面<script src="/socket.io/socket.io.js"></script> 这样引用js代码没搞明白,百度搜索了一下,有人解释说是因为express提供的框架转化了路径,所以你这样做是可以引用到该js的,刚接触应该会感到意外,但是我实验如果你只是引用了express而不是用express创建项目的话可能还是不管用。

      ②、在体验Demo并且看其他人写的例子中发现,很多情况下客户端和服务端触发的事件名称都相同,不理解这种情况他们是同一个事件吗? 会不会产生冲突呢?

 

效果图

1、系统初始化,当你打开页面时会提示你连接至服务器,你输入第一条消息就是昵称。

 

2、输入昵称,以同样的方式再打开几个Tab页,输入昵称。

 

3、两个客户端聊天

 

 

服务端实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
var express=require('express');
var app=express();
var http=require('http').Server(app);
var io=require('socket.io')(http);
 
app.get('/',function(req,res){
    res.sendFile(__dirname+'/index.html');
});
 
var onlineUserCount=0; //客户端连接数量
var onlineUsers={}; //统计客户端登录用户
 
io.on('connection',function(socket){
    socket.emit('open');  //通知客户端已连接
     
    //构造客户端对象
    var client={
        socket:socket,
        name:false
    }
     
    //监听客户端的chat message事件, 该事件由客户端触发
    //当服务端收到消息后,再把该消息播放出去,继续触发chat message事件, 然后在客户端监听chat message事件。
    socket.on('chat message',function(msg){
        console.log('chat message:'+msg);
        var obj={time:getTime()}; //构建客户端返回的对象
         
        //判断是不是第一次连接,以第一条消息作为昵称
        if(!client.name){
            onlineUserCount++;
             
            client.name=msg;
            obj['text']=client.name;
            obj['author']='Sys';
            obj['type']='welcome';
            obj['onlineUserCount']=onlineUserCount;
            socket.name=client.name; //用户登录后设置socket.name, 当退出时用该标识删除该在线用户
            if(!onlineUsers.hasOwnProperty(client.name)){
                onlineUsers[client.name]=client.name;
            }
            obj['onlineUsers']=onlineUsers; //当前在线用户集合
            console.log(client.name+' login,当前在线人数:'+onlineUserCount);
 
            //返回欢迎语
            socket.emit('system',obj);  //发送给自己的消息
            //广播新用户已登录
            socket.broadcast.emit('system',obj); //向其他用户发送消息
        }else{
            //如果不是第一次聊天,则返回正常的聊天消息
            obj['text']=msg;
            obj['author']=client.name;
            obj['type']='message';
            console.log(client.name+' say:'+msg);
 
            socket.emit('chat message',obj); //发送给自己的消息 , 如果不想打印自己发送的消息,则注释掉该句。
            socket.broadcast.emit('chat message',obj); //向其他用户发送消息
 
        }
        //io.emit('chat message',msg);
    });
 
    socket.on('disconnect',function(){
        onlineUserCount--;
 
        if(onlineUsers.hasOwnProperty(socket.name)){
            delete onlineUsers[client.name];
        }
 
        var obj={
            time:getTime(),
            author:'Sys',
            text:client.name,
            type:'disconnect',
            onlineUserCount:onlineUserCount,
            onlineUsers:onlineUsers
        };
 
        //广播用户退出
        socket.broadcast.emit('system',obj); //用户登录和退出都使用system事件播报
        console.log(client.name+' disconnect,当前在线人数:'+onlineUserCount);
    });
 
     
});
 
http.listen(3000,function(){
    console.log('server begin...');
});
 
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)];
}

 

客户端实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<!doctype html>
<html>
  <head>
    <title>Socket.IO chat</title>
    <style>
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      div { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      div input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      div button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
      p{padding:5px 10px;}
    </style>
  </head>
  <body>
    <p id="onlineUser">在线人数:0</p>
    <ul id="messages"></ul>
     
    <div action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </div>
    <script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
    <script src="http://code.jquery.com/jquery-1.11.1.js"></script>
    <script type="text/javascript">
       var myName=false;
        
       var socket= io('http://localhost:3000');
       socket.on('open',function(){
          $('#messages').append($('<li>').text('已连接至服务器,请输入昵称'));
       });
 
       //监听system事件,判断welcome或者disconnect,打印系统消息
       socket.on('system',function(json){
          var sep='';
          var onlinehtml='';
          var onlineUsers=json.onlineUsers;
          for(key in onlineUsers){
            if(onlineUsers.hasOwnProperty(key)){
              onlinehtml+=sep+onlineUsers[key];
              sep='、';
            }
          }
             
          if(json.type==='welcome'){
            $('#messages').append($('<li>').text('Sys('+json.time+')welcome '+json.text));          
            $('#onlineUser').text('在线人数:'+json.onlineUserCount+'。在线列表:'+onlinehtml);
          }else if(json.type==='disconnect'){
            $('#messages').append($('<li>').text('Sys('+json.time+')bye '+json.text+''));    
            $('#onlineUser').text('在线人数:'+json.onlineUserCount+'。在线列表:'+onlinehtml);
          }
       });
 
       //监听服务端的chat message事件,接受每一条消息
       socket.on('chat message',function(json){
        $('#messages').append($('<li>').text(json.author+'('+json.time+')'+':'+json.text));
       });
 
 
       $('#m').keydown(function(e){
          if(e.keyCode===13){
            socket.emit('chat message',$('#m').val());
             
            //socket.send($('#m').val());
            $('#m').val('');
            if(myName===false){
              myName=$('#m').val();
            }
          }
       })
    </script>
  </body>
</html>

 

总结

     做这个Demo的过程中,感觉目前用到最多的就是订阅事件发布事件,然后客户端和服务端接受相应的参数,另外一个就是服务端和客户端通信可以完全用JSON格式传参,的确很方便。 目前掌握的方法就是socket.emit()和socket.broadcast.emit(),还没有搞明白emit()和send()的区分。

     提供代码下载地址:http://pan.baidu.com/s/1mgm12Rm

从helloworld开始构建一个node.js+socket.io+express4实时应用示例

查看一下node.js和npm(模块管理)版本号node -v v0.12.0 npm -v 2.5.1 先运行个小例子进入示例根目录,如/data/www/hello 新建helloworld.j...
  • keyunq
  • keyunq
  • 2015年03月26日 13:56
  • 15757

使用express + socket.io实现多房间聊天应用

原文地址:http://www.jianshu.com/p/40d8bc17529f socket.io简介 Socket.IO是一个开源的WebSocket库,它通过Node.js实现W...
  • u010874036
  • u010874036
  • 2016年07月18日 22:34
  • 2228

nodejs express的快速入门

安装首先假定你已经安装了 Node.js,接下来为你的应用创建一个目录,然后进入此目录并将其作为当前工作目录。 Node.js:https://nodejs.org/en/ $ mkdir mya...
  • Msmile_my
  • Msmile_my
  • 2016年08月16日 13:03
  • 1468

node.js中Socket.IO的进阶使用技巧

http://www.jb51.net/article/57091.htm 在上一篇博文Socket.IO中,我简要介绍了Socket.IO的基本使用方法并创建了一个简单的聊天室DEMO。本...
  • dl425134845
  • dl425134845
  • 2016年08月03日 17:01
  • 1237

用node.js(socket.io)实现数据实时推送

在做商品拍卖的时候,要求在商品的拍卖页面需要实时的更新当前商品的最高价格。实现的方式有很多,比如: 1.setInterval每隔n秒去异步拉取数据(缺点:更新不够实时) 2. AJAX轮...
  • wx_mdq
  • wx_mdq
  • 2014年02月19日 13:18
  • 1034

nodejs如何推送消息到浏览器(socket.io)

了解下 WebSocket 协议及socket.io。nodejs和socket.io是不错的组合,对于不支持 WebSocket 协议的也做了轮询的fallback,使用很简单(来自于socket....
  • z69183787
  • z69183787
  • 2016年09月11日 18:54
  • 2007

Node.js快速入门

Node.js快速入门1、Node.js安装与配置1.1 Node.js安装(1)源码编译安装下载最新版源码:https://nodejs.org/dist/v6.9.5/node-v6.9.5.ta...
  • chengyuqiang
  • chengyuqiang
  • 2017年02月22日 16:16
  • 2177

菜鸟学习nodejs--Socket.IO即时通讯

动态web在html5以前,web的设计上并没有考虑过动态,他一直是围绕着文档设计的,我们看以前比较老的网站,基本上都是某一刻用来显示单一的文档的,用户请求一次web页面,获取一个页面,但是随着时间的...
  • lovemenghaibin
  • lovemenghaibin
  • 2016年04月27日 20:33
  • 12913

使用socket.io+express实现网页聊天的实践

近期,有客户提出希望尝试用HTML5相关技术实现在线交互和文件传输,于是乎找到了socket.io,通过搜索引擎和官方帮助实现了简单的聊天和指定用户的消息广播,在此总结跟大家分享。...
  • gisxy
  • gisxy
  • 2014年02月26日 19:04
  • 1640

用node.js(socket.io)实现数据实时推送

在做商品拍卖的时候,要求在商品的拍卖页面需要实时的更新当前商品的最高价格。实现的方式有很多,比如: 1.setInterval每隔n秒去异步拉取数据(缺点:更新不够实时) 2. AJA...
  • oMingZi12345678
  • oMingZi12345678
  • 2014年11月19日 12:29
  • 3216
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Node.js、Express、Socket.io 入门
举报原因:
原因补充:

(最多只允许输入30个字)