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这个东东,说是可以用它来简单的实现实时双向的基于事件的通讯机制.我便看了一 ...
随机推荐
- shell脚本参数
举例说:脚本名称叫test.sh 入参三个: 1 2 3运行test.sh 1 2 3后$*为"1 2 3"(一起被引号包住)$@为"1" "2&qu ...
- bat脚本 -- 初步接触
服务器上的Tomcat 经常过一段时间就会死掉,为了防治Tomcat突然当掉影响业务,设置一个定时重启计划. bat脚本如下: @echo restart tomcat6 service, log t ...
- java发送 get请求
package com.java.base; import java.io.BufferedReader; import java.io.InputStreamReader; import java. ...
- JavaWeb chapter 2 Servlet
1. 什么是Servlet: Servlet是运行于Web容器中,按照其自身规范编写的Java应用程序. Servlet是用Java语言编写的,它是一个Java类,因而Servlet遵守所有Java ...
- CSS动画 防止动画结束后,回归原位
animation-fill-mode防止动画结束后,回归原位 animation: arrowsfirst 1s; animation-timing-function: linear; animat ...
- 收集Github上的iOS控件和开发资料
文章来源:http://www.mobile-open.com/2015/85017.html 动画 awesome-ios-animation 收集了iOS平台下比较主流炫酷的几款动画框架 RCTR ...
- 【php常用】常用函数啥的
1.intval() 把变量转换成整数类型 2.trim() 去除字符串两边空格or 加上参数是去除该参数 3.array_values() 函数返回一个包含给定数组中所有键值的数组,但不保留键名 ...
- 《C++primer》v5 第2章 变量和基本类型 读书笔记 习题答案
2.1 int,long long ,short 可表示范围和占用内存空间不同.具体与计算机有关. 无符号类型只能表示0和正数,带符号类型可以表示负数,0,正数. float是单精度,一般占用4个字节 ...
- Struts2之过滤器和拦截器的区别
刚学习Struts2这个框架不久,心中依然有一个疑惑未解那就是过滤器和拦截器的区别,相信也有不少人跟我一样对于这个问题没有太多的深入了解 那么下面我们就一起来探讨探讨 过滤器,是在java web中, ...
- in_array 查询数组中是否存在某个值
(PHP 4, PHP 5) in_array — 检查数组中是否存在某个值 说明 bool in_array ( mixed $needle , array $haystack [, bool $s ...