Node创建TCP聊天

//创建新的tcp服务器
var net = require(‘net‘);
var chatServer = net.createServer()

chatServer.on(‘connection‘,function(client){
    client.write(‘Hi\n‘);
    client.write(‘Bye\n‘);
    client.end();
})

chatServer.listen(9000)

/*代码的第一行,我们加载了net模块。这个模块包含了Node需要的所有TCP功能。
接着我们调用net.createServer()方法来厂车间一个新的TCP服务器。有了这个
服务器我们需要他做点事。这里调用on()方法来添加一个事件监听器每当有新的客户端
通过网络连接接入服务器,就会触发connection事件,事件监听器就会调用我们指定的函数。
链接事件在调用回调函数是,会传给我们新的客户端对应的TCP scoket对象的引用。我们把
他引用命名为client。调用client.write(),就能发送信息给该客户端,然后调用client.end()
方法关闭连接。
*/

//监听所有的链接请求
var net = require(‘net‘);
var chatServer = net.createServer()

chatServer.on(‘connection‘,function(client){
    client.write(‘Hi\n‘);

client.on(‘data‘,function(data){
        console.log(data)
    })

})

chatServer.listen(9000)

/*这里添加了另外一个事件监听器,调用的是client.on()。注意我们是在connection回调函数作用域
中添加事件监听器,这样就能访问到链接事件所对应的client对象。新监视器关注的是data事件,每当
client发送数据给服务器时,这一事件都会触发*/

//客户端之间的通信
var net = require(‘net‘)

var chatServer = net.createServer(),
    clientList = []
chatServer.on(‘connection‘,function(client){
    client.write(‘Hi!\n‘);

clientList.push(client)

client.on(‘data‘,function(data){
        for (var i = 0; i < clientList.length; i+=1) {
            //把数据发送给客户端
            clientList[i].write(data)
        }
    })
})

chatServer.listen(9000)
/*服务器没有接收记录他收到的任何消息,而且把列表中的每个客户端都轮询一遍,
并把消息转发出去,发送消息的时候,没有检查发送者是谁,只是简单的把消息转发
给所有的客户端*/

//改进消息发送
var net = require(‘net‘)
var chatServer =net.createServer(),
    clientList = []

chatServer.on(‘connection‘,function(client){
    client.name = client.remoteAddress + ‘:‘ + client.remotePort
    client.write(‘Hi ‘ + client.name + ‘\n‘);

clientList.push(client)

client.on(‘data‘,function(data){
        broadcase(data,client)
    })
})

function broadcase(message,client){
    for(var i = 0;i < clientList.length;i += 1){
        if(client !== clientList[i]){
            clientList[i].write(client.name + "says: " + message + ‘\n‘)
        }
    }
}

chatServer.listen(9000)
/*在connection事件监听器上为每个client对象上增加name属性
为什么我们能为client对象添加属性
因为闭包绑定了每个client对象和相应的请求。于是,在闭包内疚可以利用
client.remoteAddress和client.remotePort来创建client和name属性
client.remoteAddress是客户端所在的IP地址
client,remotePort是客户端接收从服务器返回数据的TCP端口
当不同的客户端从一个IP发起连接时,他们各自会有唯一的remotePort。
以后再向client发送消息时,我们就能唯一标识来找到他

我们还把处理data的事件监听器放到了broadcast函数中,这样,通过
调用broadcast函数就可以把消息发送到所有客户端。这一次,把发起消息
data的client对象传递进去,以便把他从接收消息的客户端列表中排除掉。
我们还把client.name加到要发送的消息上,好让其他客户端清楚消息来源*/

/*此种通信弊端:建立3个tcp通信,当断掉其中一个,在向其发送消息,即
调用broadcast()的时候,服务器会往一个断开的客户端写入数据,因为他所对应
的socket已经无法写入和读取了,而对socket进行write()操作时,Node程序会抛出
异常,这将导致其他服务器掉线
这个问题应该从两个方面来解决,首先保证在一个客户端断开的时候,要把他从客户端
列表中移除,防止他在调用write方法。V8引擎也会把相应的scoket对象作为垃圾回收
并释放内存。其次,更保险的方式不调用write方法*/

//把聊天服务器改造的更加健壮
var net = require(‘net‘)
var chatServer =net.createServer(),
    clientList = []

chatServer.on(‘connection‘,function(client){
    client.name = client.remoteAddress + ‘:‘ + client.remotePort
    client.write(‘Hi ‘ + client.name + ‘\n‘);

clientList.push(client)

client.on(‘data‘,function(data){
        broadcase(data,client)
    })

client.on(‘end‘,function(){
        clientList.splice(clientList.indexOf(client),1)
    })
})

function broadcase(message,client){
    for(var i = 0;i < clientList.length;i += 1){
        if(client !== clientList[i]){
            clientList[i].write(client.name + "says: " + message + ‘\n‘)
        }
    }
}

chatServer.listen(9000)
/*先处理断开的客户端。当一个客户端断开时,要把它从客户端列表移除。这时
可以用end事件来完成。一个socket断开连接会触发end事件,表示他要关闭。
此时,调用Array.splice()将客户端从cliectList列表移除。Array.indexOf()
方法用于找到客户端在列表的位置,然后splice()把他从列表移除。之后,
下一个客户端调用broadcast方法时,已经断开的客户端将不出现在列表中*/

//检查socke的可写状态
var net = require(‘net‘)
var chatServer =net.createServer(),
    clientList = []

chatServer.on(‘connection‘,function(client){
    client.name = client.remoteAddress + ‘:‘ + client.remotePort
    client.write(‘Hi ‘ + client.name + ‘\n‘);

clientList.push(client)

client.on(‘data‘,function(data){
        broadcase(data,client)
    })
})

function broadcase(message,client){
    var cleanup = []
    for(var i = 0;i < clientList.length;i += 1){
        if(client !== clientList[i]){
            if(clientList[i].writable){
                clientList[i].write(client.name + "says: " + message + ‘\n‘)
            } else{
                cleanup.push(clientList[i])
                clientList[i].destroy()
            }
        }
    }
    //在写如入循环中删除死节点,消除垃圾索引
    for(i = 0;i < cleanup.length;i += 1){
        clientList.splice(clientList.indexOf(cleanup[i]),1)
    }
}

chatServer.listen(9000)
/*调用broadcast函数的时候,检查一下socket是否可写,以确保不会因为任何一个不可写
的socket导致异常。不仅如此,发现任何不可写的socket后,还要通过Socket.destroy()
方法将其关闭并从clientList中移除。注意,遍历clientList的过程没有移除socket,*/

时间: 2024-10-10 23:34:41

Node创建TCP聊天的相关文章

Nodejs创建TCP服务器

Nodejs创建TCP服务器 1.Nodejs提供了net模块给我们,所以我们创建TCP服务器很简单: 1 require('net').createServer(function(socket) { 2 // new connection 3 socket.on('data', function(data) { 4 // got data 5 }); 6 socket.on('end', function(data) { 7 // connection closed 8 }); 9 socke

Node实战之聊天室

Node实战之聊天室 Node如何同时处理Http和WebSocket 1.只出现在用户访问聊天程序网站时:Web浏览器->Http请求->Node服务器->Http响应->Web浏览器 2.在用户聊天时持续发生:Web浏览器->WebSocket数据发送->Node服务器->WebSocket数据接收->Web浏览器 开始搭建 1.创建程序文档结构(如下图所示) 2.指明依赖项 程序的依赖项是在package.json文件中指明的.这个文件总是被放在程序的

《转》 Openstack Grizzly 指定 compute node 创建 instance

声明:此文档仅仅做学习交流使用,请勿用作其它商业用途 作者:朝阳_tony 邮箱:[email protected] 2013年6月4日9:37:44 星期二 转载请注明出处:http://blog.csdn.net/linzhaolove 有时我们有几个 compute node .openstack默认是进行平衡创建,但有是我们想将某个instance 特定创建在某个compute node ,我们该如何做呢? 1.查看挂接的节点 查看一下我们挂接了哪些compute node,如我已经成功

使用Python或Node创建简单web服务器和FTP服务器实现文件共享

有时我们需要给旁边的人传一些文件,如果大家都用windows或者mac,那么皆大欢喜,直接用QQ传就可以了,但如果有个不省心的家伙用linux怎么办?可以用网盘或者U盘,或者另外一种更酷一些的方法来实现文件共享. 使用Python(2.6-2.7)创建简单的web服务器 进入某目录,执行 python -m SimpleHTTPServer port 即可创建一个局域网内可用的web服务器.使用ip:port进行访问. 使用Node创建简单的web服务器 首先执行一下命令安装http-serve

用C#基于WCF创建TCP的Service供Client端调用

本文将详细讲解用C#基于WCF创建TCP的Service供Client端调用的详细过程 1):首先创建一个Windows Service的工程 2):生成的代码工程结构如下所示 3):我们将Service1改名为MainService 4): 添加一个Interface来定义Service的契约 4.1):截图如下所示 4.2):IOrderService.cs的代码如下所示 using System; using System.Collections.Generic; using System

【Swoole】简单安装与创建TCP服务器

pecl install swoole PHP的异步.并行.高性能网络通信引擎,使用纯C语言编写,提供了php语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS查询. Swoole内置了Http/WebSocket服务器端/客户端.Http2.0服务器端. Swoole可以广泛应用于互联网.移动通信.企业软件.云计算.网络游戏.物联网(IOT).车联网.智能家居等领域. 使用PHP

026.3 网络编程 TCP聊天

分为客户端和服务端,分别进行收发操作##########################################################################客户端:###思路:1.建立tcp客户端服务    1.1因为是面向连接,必须有连接才有通信    1.2在创建客户端时,就必须明确目的地址和端口2.一旦连接建立,就有了传输数据的通道.就可以在通道中进行数据传输,这个传输是通过流实现的,是socket  io流3.获取socket  io中的写动作就可以发送给服务

swoole 创建tcp服务器

server.php <?php /** * 创建tcp服务器 * Date: 2019/1/15 */ $serv = new swoole_server('127.0.0.1', 9501); // 监听连接进入事件 $serv->on('connect', function ($serv, $fd) { echo "Client: Connect.\n"; }); // 监听数据接收事件 $serv->on('receive', function ($serv,

TCP协议的初始化及socket创建TCP套接字描述符

我们依然从start_kernel说起,它最后会执行: arch_call_rest_init() --> rest_init() --> Kernel_init() --> Kernei_init_freeable() --> do_basic_setup() --> do_initcalls() --> do_initcall_level(level) do_initcall_level(level)会根据level从0级开始以次执行相应先后等级的初始化函数. 第一