在学习node的时候都会练习做一个聊天室的项目,主要使用socket.io模块和http模块。这里我们使用更加原始的方式去写一个在命令行聊天的聊天室。
http模块,socket.io都是高度封装之后的模块,我们使用更加原始的net模块来做。
socket
做聊天室,我们首先要了解一下socket,用百度百科上的定义:网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。socket对TCP/IP封装提供网络开发的接口,提供网络通信的接口。详细可以看看各种百科的资料。
服务端
1.基本接口介绍
创建服务端
const server = net.createServer((socket) => {//这里的毁掉函数中的参数就是一个socket
}
//监听端口和主机
server.listen({port:4433,host:'127.0.0.1'//要想别人访问到,要写服务启动所在机子的ip地址,默认localhost
}, () => {//这里是启动成功后的回调console.log('server bound')
})
服务创建成功之后,socket可以提供客户端(访问者)的一些信息,这里主要用的两个属性
socket.remoteAddress :客户端的ip地址
socket.remotePort:客户端访问的接口,这里是随机分配,注意这里的接口跟我们创建服务的接口不同,表示的意义也不一样建立网络通信连接至少要一对端口号,服务端监听的端口是为了跟服务端所在机子的其他服务区分,客户端访问这个端口的时候自然也要区分,分配不同端口
socket的event事件
//监听客户端发送过来的消息
socket.on('data', (data) => {//这里data是一个buffer要转化为字符串,然后去一下两端空格let receive = JSON.parse(data.toString().trim());})
//给客户端发送消息
socket.write(string[,encoding]);
错误处理error
socket.on('error', (err) => {//在测试中发现,不去监听这个错误事件,当你客户端掉线之后服务端也会断开所以做一些错误处理})
2.聊天设计
聊天过程我们分三部分
1.登录
2.跟所有人聊
3.跟特定对象聊
首先我们确定聊天信息的发送格式,就像http里面有头部,内容等。我们发送的信息,应该包括发送者名字,给谁发以及发送的消息,设定为一下格式
const send = {name:"",message:"",to:""
}
服务端要根据给谁发做不同的处理
1.登录(login):我们要给所有的人发信息,XXX登录了聊天室,还要记录这个访问的socket,以便于后续给特定的人发消息,格式{username:socket}
2.跟所有人聊天(server):除了发消息本人要给其他人发送
3.跟某一个人聊天(client):找到相应的socket发送消息
socket.on('data', (data) => {let receive = JSON.parse(data.toString().trim());switch(receive.to){case "login":DealInfo.login(receive, socket);break;case "server":DealInfo.server(receive, socket);break;default:DealInfo.client(receive, socket);break;}})
之前我们有监听socket的错误处理,也就是当用户掉线的时候,我们就可以把记录的socket删除掉,并提示当前用户数。这里可以从记录的socket个数求取,也可以根据以下方法
server.getConnections((err, count) => {if(err){throw err;}console.log(`${deleteKey}下线了 当前在线人数${count}`);})
客户端
1.基本接口介绍
创建socket连接
const client = net.connect({port:4433,host:'127.0.0.1'//默认localhost}, () => {//连接成功之后的回调})
client的事件
//监听服务端发送过来的信息
client.on('data', (data) => {//这里data是一个bufferlet receive = JSON.parse(data.toString().trim());}).on('error', (err) => {//错误处理})
//给服务端发送消息
client.wirte(string[, encoding]);
2.聊天设计
基本设置
登录:要输入聊天名再去连接客户端
群聊或者跟某一个人聊只需要区分用户即可,跟某一个人聊的输入格式为name:message
聊天格式:name>message
2.1用户名
这里我们使用readline这个模块
const readline = require('readline');
const rl = readline.createInterface({input: process.stdin,output: process.stdout
});
rl.question('What is your name >', (name) => {//回调中的参数就所输入的信息,当输入非空的时候作为用户名,之后按我们的聊天格式输出预先样式//设立设定prompt的输出内容,只要调用rl.prompt()即可rl.setPrompt(`${name.trim()}>`);rl.prompt();
}
监听用户输入
rl.on('line', (line) => {let stdinInfo = line.trim().split(':');if(stdinInfo.length == 2){//跟某个用户聊天send.to = stdinInfo[0];send.message = stdinInfo[1];}else{//跟所有人聊天send.to = "server";send.message = stdinInfo[0];}client.write(JSON.stringify(send));rl.prompt();})
详细代码地址:https://github.com/Stevenzwzhai/node-socket-chatroom