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这个东东,说是可以用它来简单的实现实时双向的基于事件的通讯机制.我便看了一 ...
随机推荐
- Node.js GET/POST请求
在很多场景中,我们的服务器都需要跟用户的浏览器打交道,如表单提交. 表单提交到服务器一般都使用GET/POST请求. 我将为大家介绍 Node.js GET/POST请求. 获取GET请求内容 由于G ...
- iOS开发网络请求——大文件的多线程断点下载
iOS开发中网络请求技术已经是移动app必备技术,而网络中文件传输就是其中重点了.网络文件传输对移动客户端而言主要分为文件的上传和下载.作为开发者从技术角度会将文件分为小文件和大文件.小文件因为文件大 ...
- 复制过来的东西也不靠谱,微信公众号第三方平台的API
API:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&veri ...
- json_decode时含有中文是解码问题(json_decode返回为null)
function myDecode($str){ $str = substr(str_replace('\"','"',json_encode($str)),1,-1); retu ...
- Sublime Text 3开启自动换行
在Submine Text 3中要开启自动换行功能只需要两个步骤: 1.找到查看(View) 2.点击弹出菜单中的自动换行即可 但是如果是在2中的话就相对麻烦少少,现在也说下其开启自动换行功能的步骤: ...
- hdu 4336 Card Collector
dp+状态压缩 #include<cstdio> using namespace std; ]; <<]; int main() { int n; while(scanf(&q ...
- Java-->Tomcat(免费的Java Web服务器)
--> 要在浏览器访问一个Java Web项目,首先需要将这个项目放到服务器中. --> Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器. --> ...
- 台球游戏的核心算法和AI(1)
前言: 08年的时候, 写过一个台球游戏, 用的是java, 不过代码真的是用传说中的神器notepad写的(你信吗? 其实是用GVIM写的, ^_^), 很多类都在同一java文件中编写. 可见当时 ...
- bootstrap-10
实现原理: 通过定义容器大小,平分12份(也有分为24份或32份,但12份是最常见的),在调整内外边距,最后结合媒体查询,就制作除了强大的响应式网格系统. 工作原理: 1.数据行(.row)必须包含在 ...
- position置顶或某固定位置 兼容ie6ie7
用absolute来模拟fixed效果: /*相当于正常的position:fixed;top:0 */.sl_fixed_top{bottom:auto;top:0;_bottom:auto;_to ...