nodejs初探(四)实现一个多人聊天室
我们实现的思路是,当有一个人发送过来消息,我们就广播给其他客户端。
var net = require('net');
var chatServer = net.createServer(),
clientList = [];//已连接的client列表
chatServer.on('connection', function(client) {
// name 的自定义属性,用于表示哪个客户端(客户端的地址+端口为依据)
client.name = client.remoteAddress + ':' + client.remotePort;
client.write('Hi ' + client.name + '!\n');
//加入在线列表
clientList.push(client);
client.on('data', function(data) {
broadcast(buffer, client);// 发送给其他客户端
});
client.on('end', function() {
//从在线列表中移除
clientList.splice(clientList.indexOf(client), 1);
});
});
chatServer.listen(9000);
这里broadcast方法发送给其他客户端,代码如下
function broadcast(message, client) {
for(var i=0;i<clientList.length;i+=1) {
//发送给其他人
if(client !== clientList[i]) {
var msg=client.name + " says: " + message;
console.log(msg);
clientList[i].write(msg);
}
}
}
但此时,我们会发现,每发送一个字符,其他客户端都会收到一条消息。
比如我们发送”abcd“,如果client.name为”192.168.1.2:5486“,其他用户收到的是:
192.168.1.2:5486 says: a
192.168.1.2:5486 says: b
192.168.1.2:5486 says: c
192.168.1.2:5486 says: d
此时,我们需要考虑分割符将我们要发送的完整的一句话分开,最终我采取的是回车换行分割。最终代码如下:
// 在前者的基础上,实现 Client --> Sever 的通讯,如此一来便是双向通讯
var net = require('net');
var chatServer = net.createServer(),
clientList = [];//已连接的client列表
var clientsBuffer={};
//telnet 127.0.0.1 9000
chatServer.on('connection', function(client) {
// name 的自定义属性,用于表示哪个客户端(客户端的地址+端口为依据)
client.name = client.remoteAddress + ':' + client.remotePort;
client.write('Hi ' + client.name + '!\n');
clientList.push(client);
clientsBuffer[client.name]=new Buffer(0);//发送消息的缓存
client.on('data', function(data) {
console.log(data);
var myBuffer=clientsBuffer[client.name];
console.log(myBuffer);
//以回车换行为分割
if(data.equals(new Buffer([0x0d,0x0a]))){
broadcast(myBuffer, client);// 接受来自客户端的信息
clientsBuffer[client.name]=new Buffer(0);//清空缓存
}else{
//将发送过来的字符拼入缓存中
var buflist=[myBuffer,data];
clientsBuffer[client.name]=Buffer.concat(buflist,myBuffer.length+data.length);
} });
client.on('end', function() {
clientList.splice(clientList.indexOf(client), 1); // 删除数组中的制定元素。这是 JS 基本功哦~
});
client.on('error', function(e) {
console.log(e);
});
});
/**
* 广播给其他所有用户
* @param message 消息内容
* @param client 发送人客户端
*/
function broadcast(message, client) {
var cleanup = [];//需要销毁的列表
for(var i=0;i<clientList.length;i+=1) {
if(client !== clientList[i]) {
if(clientList[i].writable) { // 先检查 sockets 是否可写
var msg=client.name + " says " + message;
console.log(msg);
clientList[i].write(msg);
} else {
cleanup.push(clientList[i]) // 如果不可写,收集起来销毁。销毁之前要 Socket.destroy() 用 API 的方法销毁。
clientList[i].destroy()
}
}
}
//销毁
for(i=0;i<cleanup.length;i+=1) {
clientList.splice(clientList.indexOf(cleanup[i]), 1)
}
}
chatServer.listen(9000);
nodejs初探(四)实现一个多人聊天室的更多相关文章
- 与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室
原文:与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...
- 与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室
原文:与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...
- 使用Go语言+Protobuf协议完成一个多人聊天室
软件环境:Goland Github地址 一.目的 之前用纯逻辑垒完了一个可登入登出的在线多人聊天室(代码仓库地址),这次学习了Protobuf协议,于是想试着更新下聊天室的版本. 主要目的是为了掌握 ...
- Asp.net MVC + Signalr 实现多人聊天室
Asp.net SignalR 简介: 首先简单介绍一下Signalr ,我也是刚接触,觉得挺好玩的,然后写了一个多人聊天室. Asp.net SignalR 是为Asp.net 开发人员提供的一个库 ...
- 利用Node.js的Net模块实现一个命令行多人聊天室
1.net模块基本API 要使用Node.js的net模块实现一个命令行聊天室,就必须先了解NET模块的API使用.NET模块API分为两大类:Server和Socket类.工厂方法. Server类 ...
- Apache MiNa 实现多人聊天室
Apache MiNa 实现多人聊天室 开发环境: System:Windows JavaSDK:1.6 IDE:eclipse.MyEclipse 6.6 开发依赖库: Jdk1.4+.mina-c ...
- C 基于UDP实现一个简易的聊天室
引言 本文是围绕Linux udp api 构建一个简易的多人聊天室.重点看思路,帮助我们加深 对udp开发中一些api了解.相对而言udp socket开发相比tcp socket开发注意的细节要少 ...
- java socket之多人聊天室Demo
一.功能介绍 该功能实现了一个类似QQ的最简单多人聊天室,如下图所示. 二.目录结构 三.服务端 1)SocketServer类,该类是服务端的主类,主要负责创建聊天窗口,创建监听客户端的线程: pa ...
- 玩转Node.js(四)-搭建简单的聊天室
玩转Node.js(四)-搭建简单的聊天室 Nodejs好久没有跟进了,最近想用它搞一个聊天室,然后便偶遇了socket.io这个东东,说是可以用它来简单的实现实时双向的基于事件的通讯机制.我便看了一 ...
随机推荐
- zookeeper学习系列:一、入门
基本是 http://zookeeper.apache.org/doc/trunk/zookeeperOver.html 的翻译,应用场景摘抄:http://www.wuzesheng.com/?p= ...
- iOS开发网络篇—监测网络状态
iOS开发网络篇—监测网络状态 一.说明 在网络应用中,需要对用户设备的网络状态进行实时监控,有两个目的: (1)让用户了解自己的网络状态,防止一些误会(比如怪应用无能) (2)根据用户的网络状态进行 ...
- JAVA 集合List、Map、Set
Collection(接口) Set(接口) HashSet(类) … List(接口) ArrayList(类) Vector(类) LinkedList(类) … Map(接口) HashMap( ...
- 64位Win7系统下vs2010调试无法连接oracle
64位win7系统的Program Files (x86)路径中有括号,oracle不认识这样的路径,所以就出现不能连接数据库的问题.所以我们可以将vs2010的内部调试web服务器WebDev.We ...
- js事件捕获,事件冒泡,事件委托以及DOM事件流
一:DOM事件流: 事件流是从页面接收事件的顺序,DOM2级事件规定事件流包括三个阶段: ①事件捕获阶段:用意在于事件达到目标之前捕获它,在事件捕获阶段事件流模型:document→html→body ...
- 关于ASP.NET页面打印技术的总结【转】
B/S结构导致了Web应用程序中打印的特殊性. • 程序运行在浏览器中,打印机在本地,而文件确可能在服务器上,导致了打印控制不是很灵活. • 格式如何控制和定制等,是我们开发中可能会面对的问题. 打印 ...
- Maven项目的核心pom.xml解释(转)
文章转自http://blog.sina.com.cn/s/blog_534f69a001010lpv.html maven项目的核心是pom.xml.POM(Project Object Model ...
- easyUI笔记09.03
layout的布局可以自适应 <body class="easyui-layout"> <div data-options="region:'north ...
- LNMP安装一键安装包
系统需求: CentOS/Debian/Ubuntu Linux系统 需要2GB以上硬盘剩余空间 128M以上内存,OpenVZ的建议192MB以上(小内存请勿使用64位系统) VPS或服务器必须已经 ...
- IOS ASIFormDataRequest使用简介(2/25)
ASIHTTPRequest类库中的ASIFormDataRequest是实现HTTP协议中的处理POST表单的很好的类库.使用起来非常简单.下面特酷吧简要总结其用法. 在说明之前先需要了解HTTP请 ...