样例地址http://www.lxrtalk.com/

我们实现的思路是,当有一个人发送过来消息,我们就广播给其他客户端。

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

转载于:https://www.cnblogs.com/lixiaoran/p/5041015.html

nodejs初探(四)实现一个多人聊天室相关推荐

  1. Android Socket通信(五) -- 实现一个多人聊天室

    系列文章: Android Socket 系列更新计划 Android Socket通信(一) – 初识与相遇 Android Socket通信(二) --UDP,单播,广播和多播(组播) Andro ...

  2. 9. nio实现一个多人聊天室

    文章目录 NIO实现一个多人聊天室 1.服务端 2.客户端 3.客户端处理器 4.多客户端启动 NIO实现一个多人聊天室 1.服务端 package ys.server;import org.slf4 ...

  3. 使用Go语言+Protobuf协议完成一个多人聊天室

    软件环境:Goland Github地址 一.目的 之前用纯逻辑垒完了一个可登入登出的在线多人聊天室(代码仓库地址),这次学习了Protobuf协议,于是想试着更新下聊天室的版本. 主要目的是为了掌握 ...

  4. 10分钟教对象搭建了一个多人聊天室~

    Demo演示 体验demo链接: http://socket.vjscoder.com/websocket-chatroom/index.html#/ 去github查看完整源码: https://g ...

  5. ajax 多人聊天吧,基于Nodejs利用socket.io实现多人聊天室

    socket.io简介 在Html5中存在着这样的一个新特性,引入了websocket,关于websocket的内部实现原理可以看这篇文章,这篇文章讲述了websocket无到有,根据协议,分析数据帧 ...

  6. 基于 Vue 开发一个 多人聊天室(万字长文) - 从 0 到 1 篇

    前言 在上个月初,接到一个需求,要开发一个 聊天通讯 模块 并且 集成到 项目中的多个 入口,实现业务数据的记录追踪. 接到需求后,还挺开心,这是我第一次 搞 通讯 类的需求,之前一直是 B 端 的业 ...

  7. 使用nodejs+Socket打造P2P实现多人聊天室

  8. 基于socket实现的多人聊天室项目(python)

    最近做了一个多人聊天室项目,主要目的是练习和巩固socket编程. 在开始之前,可以先了解一下socket的TCP三次握手和四次挥手. 参考:https://blog.csdn.net/luoyoub ...

  9. java 多人聊天室_Java高效NIO之多人聊天室

    系统功能 使用NIO实现一个多人聊天室.聊天室包含以下功能. 服务端 处理客户连接 新连接客户端注册名字,并进行重名判断 新用户注册后向客户端广播用户列表 接收客户端消息并单播或广播 客户端 向服务端 ...

最新文章

  1. 【红黑vip提权教程和饭客vip2010***教程全套】
  2. mysql的字符串函数
  3. redis一般缓存什么样数据_Redis缓存和MySQL数据一致性方案详解
  4. php进程学习(一)
  5. 石头扫地机器人离线了怎么办_关于激光头故障,石头扫地机器人无限次复活记!...
  6. 2019最新拼多多Java面试题:幻影读+分段锁+死锁+Spring Cloud+秒杀
  7. mysql redis hbase_10分钟梳理MySQL核心知识点
  8. jquery设置表单元素只读_jquery设置元素readonly和disabled(checkbox只读)
  9. hdu 6015 Gameia(树上博弈)
  10. 东南大学成贤学院计算机报名,2019上半年东南大学成贤学院全国计算机等级考试预报名通知...
  11. oracle管理表空间和数据文件(笔记)
  12. 拓端tecdat|R语言马尔可夫区制转移模型Markov regime switching
  13. apipost自动化测试工具
  14. 考研408-计算机组成原理-存储系统
  15. 阿里云CDN回源OSS产生流量计费说明
  16. unity Reflection Probe
  17. C++STL之<set>和<map>
  18. 非线性可视化(3)混沌系统
  19. dos攻击与ddos攻击的区别
  20. 全国计算机一级上表格怎么做,全国计算机一级考试word表格制作(2003版)

热门文章

  1. linux下无对应分辨率,linux mint 向“显示(display)”面板添加没有提供的分辨率选项,使虚拟机中的linux mint可以全屏显示...
  2. html页面字段怎么排版,如何做好html的排版标签
  3. 排列不同的三位数c语言,C语言求助!一个三位数的逆序数,总是编不对
  4. 关于Shiro的标签应用
  5. 【PAT】2020年春季考试乙级题目、答案、摸鱼、游记、93分
  6. Windows各版本区别
  7. find linux 目录深度_把 Linux 上的文件列表和排序玩出花来
  8. Coprime Sequence
  9. Unity3D基础25:AudioSource声音组件
  10. kubernetes存储详解