局域网群聊

功能

局域网群聊,无需服务器

代码

const fs=require('fs');
const net=require('net');
var config=JSON.parse(fs.readFileSync('./config.json').toString('utf-8'));
var server=net.createServer();
var ser_fail=`:`;
var ser_son={};
var ser_node=new Set();
function make_connect(remote){
    var rem_con=remote.split(':');
    if(!ser_son[remote]){
        ser_son[remote]=net.connect(rem_con[1],rem_con[0],()=>{
            ser_son[remote].write(JSON.stringify({
                "opt":"set",
                "remote":`${config.ip}:${config.port}`,
                "fail":ser_fail,
                "node":[...ser_node,`${config.ip}:${config.port}`]
            }));
            ser_son[remote].on('error',()=>{
                ser_son[remote].destroy();
                delete ser_son[remote];
            })
        });
    }
}
server.on('connection',(client)=>{
    var son=new Set();
    var fail=`:`;
    var remote=`:`;
    client.on('data',(data)=>{
        data=JSON.parse(data.toString('utf-8'));
        if(data.opt=="set"){
            fail=data.fail;
            remote=data.remote||remote;
            if(ser_fail==`:`){
                ser_fail=remote;
                send({
                    "opt":"set",
                    "fail":remote
                });
            }
            if(data.node){
                son=new Set(data.node);
                ser_node=new Set([...ser_node,...son]);
            }
            make_connect(remote);
        }
        if(data.opt=="msg"){
            process.stdout.write(data.msg);
            send(data,remote);
        }
    })
    client.on('error',(err)=>{
        client.destroy();
    })
    client.on('close',()=>{
        delete son[remote];
        if(fail!=`:`&&fail!=`${config.ip}:${config.port}`){
            make_connect(fail);
        }
        ser_node=new Set([...ser_node].filter(node => !son.has(node)));
    })
})
server.listen(config.port,config.ip);

function send(msg,remote){
    for(var key in ser_son){
        if(key!=remote){
            ser_son[key].write(JSON.stringify(msg));
        }
    }
}

function work_message(msg){
    if(msg.slice(0,4)=="/con"){
        var arg=msg.split(' ');
        if(!ser_node.has(arg[1])){
            make_connect(arg[1]);
        }
    }
    if(msg.slice(0,4)=="/sta"){
        console.log(`node:${JSON.stringify(ser_node)}`);
        console.log(`fail:${ser_fail}`);
        console.log(`son:${JSON.stringify(ser_son)}`);
    }
    if(msg.slice(0,4)=="/exi"){
        process.exit();
    }
    if(msg[0]=="/"){
        return;
    }
    var msg=`[${config.ip}:${config.port}]${msg}\n`;
    process.stdout.write(msg);
    send({
        "opt":"msg",
        "msg":msg
    });
}
function backspace(msg){
    msg.split('').reverse().forEach((char)=>{
        process.stdout.write(`${(char>='\u4E00'&&char<='\u9fa5')?("\b"):("")}\b \b`);
    })
}
var memo="";
process.stdin.on('data',(data)=>{
    data=data.replace('\r','\n');
    if(data=='\b'){
        backspace(memo.slice(-1));
        memo=memo.slice(0,-1);
        return;
    }
    memo+=data;
    if(memo.slice(-1)=='\n'){
        memo=memo.slice(0,-1);
        backspace(memo);
        work_message(memo);
        memo="";
        return;
    }
    process.stdout.write(data);
})
process.stdin.setEncoding('utf-8');
process.stdin.setRawMode(true);
process.title=`${config.ip}:${config.port}`;

猜你喜欢

转载自www.cnblogs.com/FireHumansSkeleton/p/12724117.html