欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

nodesocket简单聊天室实现教程(代码)

程序员文章站 2022-03-07 22:50:37
一、服务端 socket服务端接受来自客户端的write内容(也可以理解成请求报文);然后广播给先有连接的所有客户端用户client const net = requi...

一、服务端


socket服务端接受来自客户端的write内容(也可以理解成请求报文);然后广播给先有连接的所有客户端用户client

const net = require("net");
const clients = [];
const port = 9999;
var client = net.createserver(socket=> {
    console.log(`server ${socket.remoteaddress} add in port ${port}`);
    clients.push(socket); //保存连入的客户
    //群聊数据处理
    function broadcast(signal,clients){
        let send = {
            protocal: signal.protocol,
            protocal: signal.from,
            protocal: signal.message,
        };
        //遍历所有客户端发送
        clients.foreach(client => {
            client.write(json.stringify(send));
        })
    }
    //接受客户端数据
    socket.on("data", (chunk) => {
        let signal = json.parse(chunk.tostring().trim());
        let protocol = signal.protocal; 
        switch(protocol) {
            case "broadcast"://群聊
            broadcast(signal,clients);
            break;
            case "p2p"://私聊
            p2p(signal);
            break;
            default:
            socket.write("到底私聊还是群聊,你告诉我啊。。。");
        }

    })  
})


client.listen(port, (err) => {
    if(err) {throw new error("端口被占用,服务启动失败")};
    console.log(`server is listened on port ${port}`);
})

二、客户端


const net = require("net");
const port = 9999;
const readline = require("readline");//用来读取输入行内容,api是有的,得找时间好好看看,据说可以逐行读取文件;

let rl = readline.createinterface(process.stdin, process.stdout);
rl.question("请输入聊天室用户名: "(name)=> {
    name = name.trim();
    //输入名字了就创建链接
    let server = net.createconnection({port:port}, () => {
        //接受服务端的返回内容
        server.on("data", (chunk) => {
            let receive = json.parse(chunk.tostring().trim());
            let protocol = receive.protocol;
            switch(protocol) {
                case "broadcast":
                console.log("\n" + receive.protocal);
                console.log(receive.from);
                console.log(receive.message);
                rl.prompt();
                break;
                //私聊
                case "p2p":
                .......//后面在写
            }
        })
        rl.setprompt(name + ">");
        rl.prompt(); //将输入写入到命令行;

        rl.on("line", (line) => {
            let send = {
                    protocol: "broadcast",
                    from: name,
                    message: line.tostring().trim(),
                }
            //发送输入的消息内容至服务端
            server.write(json.stringify(send));
        })
    })


})

小结:群聊是将接受内容遍历发送给每个存储起来的socket客户端对象,而私聊,需要根据输入的内容判断,是向谁私聊,然后点对点进行单个socket数据传输;

**可以加入在线人数,增加error事件监听,监听下线人数,当所有连接成功发送,某一个客户端突然出现发送失败,就可以简单理解为下线(简单理解,距离怎么根据网络监听在线下线还不知道。。。。)

**这只是在命令行中进行测试的案例,所以使用了readline模块。可以在html文件中操作dom元素,增添输入框,模拟一个聊天室的功能;后续试试;