node socket 简单聊天室

一、服务端


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元素,增添输入框,模拟一个聊天室的功能;后续试试;


**越努力,越幸运,加油

你可能感兴趣的:(node)