前言

周末断断续续的写了第一个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、两个客户端聊天

服务端实现

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)];
}

客户端实现

<!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

Node.js、Express、Socket.io 入门的更多相关文章

  1. Node.js 和Socket.IO 实现chat WEBIM

    socket官方:   http://socket.io/  需求:实现WEB IM功能,数据从服务器PUSH  不是PULL  websocket是基于HTML5的新特性,不兼容IE6,7,8 .. ...

  2. node.js和socket.io实现im

    im——Instant Messaging 即时通讯 基本技术原理 (1)通过IM服务器登陆或注销 (2)用户A通过列表找到B,用户B获得消息并与之交谈 (3)通过IM服务器指引建立与B单独的通讯通道 ...

  3. 使用Node.js的socket.io模块开发实时web程序

    首发:个人博客,更新&纠错&回复 今天的思维漫游如下:从.net的windows程序开发,摸到nodejs的桌面程序开发,又熟悉了一下nodejs,对“异步”的理解有了上上周对操作系统 ...

  4. node.js和socket.io纯js实现的即时通讯实例分享

    在这个例子中,其实node.js并没有真正起到服务器的作用,因为我们这里可以直接运行client.html文件,而不用输入url请求,当 然,要想输入url请求页面内容还需要加入请求静态文件的代码.这 ...

  5. [Node.js] 基于Socket.IO 的私聊

    原文地址:http://www.moye.me/2015/01/02/node_socket-io/ 引子 最近听到这么一个问题:Socket.IO 怎么实现私聊?换个提法:怎么定位到人(端),或者说 ...

  6. node.js(express)连接mongoDB入门指导

    一.写在前面 人人都想成为全栈码农,作为一个web前端开发人员,通往全栈的简洁之路,貌似就是node.js了.前段时间学习了node.js,来谈谈新手如何快速的搭建自己的web服务,开启全栈之路. 二 ...

  7. Node.js+express 4.x 入门笔记

    一.新建node项目并实现访问 二.在express4.x下,让ejs模板文件,使用扩展名为html的文件 三.实现路由功能 四.session使用 五.页面访问控制及提示 六.代码下载地址 一.新建 ...

  8. Node.js + Web Socket 打造即时聊天程序嗨聊

    前端一直是一块充满惊喜的土地,不仅是那些富有创造性的页面,还有那些惊赞的效果及不断推出的新技术.像node.js这样的后端开拓者直接将前端人员的能力扩大到了后端.瞬间就有了一统天下的感觉,来往穿梭于前 ...

  9. Windows下Node.js+Express+WebSocket 安装配置

    Linux参考: Linux安装Node.js 使用Express搭建Web服务器 Node.js是一个Javascript运行环境(runtime).实际上它是对Google V8引擎进行了封装.V ...

  10. NodeJS+Express+Socket.io的一个简单例子

    关键字:NodeJS,Express,Socket.io. OS:Windows 8.1 with update pro. 1.安装NodeJS:http://nodejs.org/. 2.初始化一个 ...

随机推荐

  1. perl 切换 dnspod 域名记录

    提供域名,dnspod 账户密码(毕竟dns密码比较重要 不能谁 cat一下都可以看到 需要base64加密),原IP,切换目标IP, #!/bin/perl use warnings; use MI ...

  2. 手机CPU和GPU厂商

    CPU: 1.苹果 (Apple) A系列 ARM授权,基于Cortex-A系列架构 A5基于Cortex-A9架构,双核,主频800M-1Ghz,内存双通道32bitLPDDR2,GPU采用Powe ...

  3. SQLPrompt 7.2发布

    SQLPrompt 7.2发布 下载地址:http://www.red-gate.com/products/sql-development/sql-prompt/ 红门的热门产品SQLPrompt 发 ...

  4. CYQ.Data V5 从入门到放弃ORM系列:框架的优势

    前言: 框架开源后,学习使用的人越来越多了,所以我也更加积极的用代码回应了. 在框架完成了:数据库读写分离功能 和 分布式缓存功能 后: 经过三天三夜的不眠不休,终于完成框架第三个重量级的功能:自动化 ...

  5. 玩转JavaScript OOP[2]——类的实现

    概述 当我们在谈论面向对象编程时,我们在谈论什么?我们首先谈论的是一些概念:对象.类.封装.继承.多态.对象和类是面向对象的基础,封装.继承和多态是面向对象编程的三大特性. JavaScript提供了 ...

  6. 探索c#之尾递归编译器优化

    阅读目录: 递归运用 尾递归优化 编译器优化 递归运用 一个函数直接或间接的调用自身,这个函数即可叫做递归函数. 递归主要功能是把问题转换成较小规模的子问题,以子问题的解去逐渐逼近最终结果. 递归最重 ...

  7. Fd.Service 轻量级WebApi框架

    News December 06 2014: Version 1.0.0.8Add Register Route Configuration iis 7 Integrated Mode: <sy ...

  8. Modern OpenGL用Shader拾取VBO内单一图元的思路和实现(2)

    Modern OpenGL用Shader拾取VBO内单一图元的思路和实现(2) 上一篇里介绍了Color-Coded Picking的思路和最基本的实现.在处理GL_POINTS时已经没有问题,但是处 ...

  9. hibernate学习笔记之四 Hibernate的增删改查

    采用JUnit测试,继承TestCase import java.util.Date; import junit.framework.TestCase; import org.hibernate.Se ...

  10. SQLite帮助类SQlitehelper 实现对SQLite数据的增删改查

    public class SQLiteHelper { public const string sConn = "Data Source=" + @"path" ...