使用原生node写一个聊天室

在学习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}

image.png

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

image.png

客户端

1.基本接口介绍

创建socket连接

const client = net.connect({
            port:4433,
            host:'127.0.0.1'//默认localhost
        }, () => {
              //连接成功之后的回调
        })

client的事件

//监听服务端发送过来的信息
client.on('data', (data) => {
                //这里data是一个buffer
                let 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();
}

Paste_Image.png

监听用户输入

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

Paste_Image.png

详细代码地址:https://github.com/Stevenzwzhai/node-socket-chatroom

posted @ 2017-05-11 17:34  故园苒苒  阅读(382)  评论(0编辑  收藏  举报