美文网首页
【管子先生的Node之旅·17】开发一款TCP的聊天程序

【管子先生的Node之旅·17】开发一款TCP的聊天程序

作者: 管子先生 | 来源:发表于2017-11-02 08:49 被阅读0次

    需求

    • 创建一个可以多人即时通讯的聊天室。
    • 用户加入时必须要设置昵称,且昵称不能相同。
    • 用户加入成功打印出成功欢迎信息和当前在线人数,并通知聊天室内其他的人。
    • 用户发送信息时,需要广播到所有的用户。
    • 当某一用户离开时也需要通知到所有的用户。

    效果演示

    net.gif

    程序实现

    服务端
    //tcpServer.js
    // 引入colors模块
    require('colors');
    // 引入net模块
    const net = require('net');
    // 在线计数器
    var count = 0,
        users = {};
    // 创建服务
    const serv = net.createServer((conn) => {
        console.log('有用户进来了'.red);
        // 用户欢迎信息
        conn.write('\n你好!欢迎来到管子聊天室!'.rainbow);
        // conn.write('\nOnline=>'.green + count);
        conn.write('\n请输入你的昵称:'.red);
        // 设置编码
        conn.setEncoding('utf-8');
        count++;
        // 代表当前链接的昵称
        let nickName;
        // 接收处理用户数据
        conn.on('data', (data) => {
            // 第一次用户回复数据视为设置昵称
            if (!nickName) {
                // 判断昵称是否已被占用
                if (users[data]) {
                    conn.write('\n该昵称已被占用,请重新设置:'.red);
                    return;
                } else {
                    nickName = data;
                    users[nickName] = conn;
                    console.log(Object.keys(users));
                    // 发布用户加入广播
                    broadcast('\n欢迎 ' + nickName);
                    broadcast('\n当前在线=>'.green + count);
                    conn.write('\n欢迎 ' + nickName);
                    conn.write('\n当前在线=>'.green + count);
                }
            } else {
                // 聊天消息
                broadcast('\n' + nickName + data.split('\r')[0]);
            }
        });
        // 监听用户离线
        conn.on('close', (c) => {
            console.log('有用户离开了'.red);
            count--;
            broadcast('\n离线=>'.red + nickName);
            broadcast('\n当前在线=>'.green + count);
            //将用户从中删除
            delete users[nickName];
        });
        // 错误处理
        conn.on('error', (err) => {
            console.error(err);
        });
        // 用户广播
    
        function broadcast(val) {
            for (let i in users) {
                if (i !== nickName) {
                    console.log(new String(i));
                    console.log(new String(nickName));
                    console.log(i == nickName);
                    users[i].write(val + ++sm);
                }
            }
        }
    });
    
    serv.listen(3030, () => {
        console.log('服务已启动'.yellow);
    });
    
    客户端
    //引入net模块
    const net = require('net');
    //端口
    const port = 3030;
    //地址
    const host = '127.0.0.7';
    //链接tcp服务端
    const client = net.connect(port, host);
    //设置编码
    client.setEncoding('utf-8');
    //监听是否链接成功
    client.on('connect', () => {
        console.log('tcp服务器已连接');
    });
    //接收服务器数据
    client.on('data', (data) => {
        process.stdin.pause()
        console.log(data);
        //打开输入流
        input();
    });
    //监听断开服务器
    client.on('close', () => {
        console.log('用户断开了服务器');
    });
    //错误处理
    client.on('error', () => {
    
    });
    //启动输入流
    function input() {
        process.stdout.write('请输入');
        process.stdin.resume();
        process.stdin.setEncoding('utf-8');
        process.stdin.once('data', option);
    }
    //发送数据
    function option(data) {
        //关闭用户输入
        process.stdin.pause()
        let datas = data.split('\r')[0];
        console.log(new String(datas));
        if (datas == 'exit') {
            //关闭与服务器的链接
            client.end('再见,各位!')
        } else {
            //往服务器发送数据
            client.write(datas);
        }
    }
    

    相关文章

      网友评论

          本文标题:【管子先生的Node之旅·17】开发一款TCP的聊天程序

          本文链接:https://www.haomeiwen.com/subject/ucknpxtx.html