nodejs 服务器实现区分多客户端请求服务
初始实现
var net = require('net');//1 引入net模块
var chatServer = net.createServer();//创建net服务器
var clientList=[];//保存多个客户端的数组
chatServer.on('connection', function (client) {//服务器连接客户端
client.name=client.remoteAddress+':'+client.remotePort;
/*增加name属性*/
client.write('Hi'+client.name+'!\n');
clientList.push(client);
client.on('data', function (data) {
/*添加事件监听器,这样就可以访问到连接事件所对应的client对象,当client发送数据给服务器时,这一事件就会触发*/
for(var i=0;i<clientList.length;i++){
if(clientList[i]!==this){
// 把数据发送给其他客户端
clientList[i].write(this.name+"says "+data);
}
}
});
});
chatServer.listen(9000, "127.0.0.1");//服务器端口
注意:这里有个坑——如果有个客户端断开连接,那么所有人都会玩完!
因为如果再往服务器发送消息,这时候服务器并不知道某个客户端已经断开了连接,因此会继续向其发送数据,但是这时断开的这个客户端对应的socket已经无法写入数据,而对已关闭的socket进行write()操作node程序会抛出异常,进而导致全军覆没。所以,这个问题应该从两个方面来解决:
(1)当客户端断开连接时,通知服务器,将其从客户端列表中移除,防止其调用write方法(V8引擎也会把响应的socket对象作为垃圾回收,并释放相应的内存);
(2)采用更保险的方式调用write()方法。
改进如下:
最后,监听客户端关闭事件,并记录错误
var net = require('net');//1 引入net模块
var chatServer = net.createServer();//创建net服务器
var clientList = [];//保存多个客户端的数组 chatServer.on('connection', function (client) {//服务器连接客户端
// console.log(' client remoteAddress =' + client.remoteAddress);
// console.log(' client remotePort = ' + client.remotePort);
client.name = client.remoteAddress + ':' + client.remotePort; /*增加name属性*/
client.write('Hi' + client.name + '!\n');
// console.log(''client.name+'connected');
clientList.push(client);
console.log('clientList length = ' + clientList.length);
for(var i = 0; i<clientList.length; i++){
console.log('client remoteAddress'+[i] + clientList[i].name);
}
client.on('data', function (data) {
/*添加事件监听器,这样就可以访问到连接事件所对应的client对象,当client发送数据给服务器时,这一事件就会触发*/
//广播消息给其他客户端
broadcast(data,client);
});
//监听客户端终止
client.on('end',function(){
console.log(''+client.name+'quit');//如果某个客户端断开连接,node控制台就会打印出来
clientList.splice(clientList.indexOf(client),1);
});
/*记录错误*/
client.on('error',function(e){
console.log(' error'+e);
}); function broadcast(message,client){
var cleanup=[];//断开了的客户端们
for (var i = 0; i < clientList.length; i++) {
if (clientList[i] !== client) {
//检查socket的可写状态
if (clientList[i].writable) {
// 把数据发送给其他客户端
clientList[i].write(client.name + "says " + message);
}else{
/*socket不可写,则将其从列表中移除*/
cleanup.push(clientList[i]);
clientList[i].destroy();
}
}
}
/*删除掉服务器的客户端数组中,已断开的客户端*/
for(var i=0;i<cleanup.length;i++){
clientList.splice(clientList.indexOf(cleanup[i]),1);
}
}
});
//服务器端口
chatServer.listen(9000, function(){
console.log("server bound : 9000");
});
nodejs 服务器实现区分多客户端请求服务的更多相关文章
- MySQL服务器是怎么处理客户端请求的
不论MySQL客户端进程和服务器进程是采用哪种方式进行通信,最后实现的效果都是:客户端进程向服务器进程发送一段文本(MySQL语句),服务器进程处理后再向客户端进程发送一段文本(处理结果).那服务器进 ...
- 客户端请求服务器端通信, Web 编程发展基础|乐字节
乐字节的小伙伴们,好久不见,甚是想念啊! 前面我发布的文章算是把Java初级基础阶段讲完了,接下来小乐将会给大家接着讲Java中级阶段——Javaweb. 首先,我们要看看Javaweb阶段主要重点掌 ...
- JSP基础知识➣客户端请求与服务端响应(三)
JSP客户端请求 浏览器请求服务器端,信息头的一些重要内容,在以后的网络编程中将会经常见到这些信息: Accept:指定浏览器或其他客户端可以处理的MIME类型.它的值通常为 image/png 或 ...
- 自己封装的Socket组件,实现服务端多进程共享Socket对象,协同处理客户端请求
DotNet.Net.MySocket是SLB.NET(Server Load Balance服务器负载均衡)项目中的核心组件. 在实际的项目中发现,单进程的服务端处理高并发的客户请求能力有限. 所以 ...
- ICE学习第四步-----客户端请求服务器返回数据
这次我们来做一个例子,流程很简单:客户端向服务器发送一条指令,服务端接收到这条指令之后,向客户端发送数据库中查询到的数据,最终显示在DataGridView上. 根据上一篇文章介绍的Slice语法,我 ...
- ajax客户端请求与服务端响应浅谈
AJAX,即Asynchronous Javascript And XML,AJAX本质是在HTTP协议的基础上以异步的方式与服务器进行通信. 所谓的异步,是指某段程序执行不会阻塞其他程序执行,其表现 ...
- http客户端请求及服务端详解
http客户端请求及服务端详解 引言 HTTP 是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和 扩展. ...
- javaWeb项目中的路径格式 请求url地址 客户端路径 服务端路径 url-pattern 路径 获取资源路径 地址 url
javaweb项目中有很多场景的路径客户端的POST/GET请求,服务器的请求转发,资源获取需要设置路径等这些路径表达的含义都有不同,所以想要更好的书写规范有用的路径代码 需要对路径有一个清晰地认知 ...
- 服务端如何获取客户端请求IP地址
服务端获取客户端请求IP地址,常见的包括:x-forwarded-for.client-ip等请求头,以及remote_addr参数. 一.remote_addr.x-forwarded-for.cl ...
随机推荐
- 关于EasyPoi导出Excel
如果你觉得Easypoi不好用,喜欢用传统的poi,可以参考我的这篇博客:Springmvc导出Excel(maven) 当然了,万变不离其宗.Easypoi的底层原理还是poi.正如MyBatis ...
- 跳转到appstore下载app的链接 记录一下
这是链接: https://itunes.apple.com/cn/app/da-dou-dou-lao-shi/id1395835036?mt=8 其中值得一提的是mt参数是啥意思 见下图:
- B. Our Tanya is Crying Out Loud
http://codeforces.com/problemset/problem/940/B Right now she actually isn't. But she will be, if you ...
- Putty等工具中解决SSH连接超时断开的问题
转自:http://www.putty.ws/putty-chaoshi 1 在 linux下的ssh命令:vim /etc/ssh/ssh_config 然后找到里面的ServerAliveInte ...
- 怎么用CIFilter给图片加上各种各样的滤镜_2
上一篇讲了怎么找到能用的的滤镜和大概怎么去寻找... 这里接着说如何详细地给图片加滤镜效果..前的准备工作... . 1. 在找到想用的滤镜名字之后.须要知道这个滤镜究竟须要什么參数. . 例如以下图 ...
- 图片在线处理 webp!
之前处理图片的方式是,小图标通过gulp配置的spritesmith雪碧图方式,.png会先用ps工具转成.jpg,然后jpg太大则用在线压缩工具来进行压缩(另外gulp系列的gulp-imagemi ...
- jquery animate() Alternate 语法
前段时间在使用jQuery的animate() 函数时候用到Alternate方式.主要是要让数字自增到指定大小,且能看见数字增加过程. 一般使用如下方式: function autoPlusAnim ...
- LaTeX源代码显示宏包listings应用备忘之新语言定义
我目前了解的LaTeX中有关源代码显示的宏包有两个,这里介绍其中的listings宏包.listings宏包中已经定义了部分计算机语言的显示样式,但还是有些语言没有定义,我们一起看一下如何定义新的 ...
- json keyname map
var obj = { fname:'zhao', lname:'yao', parents:{ father:'zhao' }, children:[ { dname:'zhaoyiyi' } ] ...
- daily Tip
daily tip : <UserControl.Resources> <Storyboard x:Name="sb1" x:Key=&quo ...