Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js UDP请求未连接到repl.it服务器_Node.js_Udp_Repl.it - Fatal编程技术网

Node.js UDP请求未连接到repl.it服务器

Node.js UDP请求未连接到repl.it服务器,node.js,udp,repl.it,Node.js,Udp,Repl.it,我正在尝试使用node.js和repl.it上的数据报编写一个简单的UDP服务器,但我无法连接到服务器,我尝试了不同的端口,但没有建立任何连接。 在服务器上运行“npm启动”后,我得到: 服务器侦听0.0.0.0:3000 就这些,问题出在哪里? 代码在本地服务器上运行良好,建立了连接并发送了数据包,但当我尝试在repl.com上运行它时,什么也没有发生 const _ = require('lodash'); const dgram = require('dgram'); const serv

我正在尝试使用node.js和repl.it上的数据报编写一个简单的UDP服务器,但我无法连接到服务器,我尝试了不同的端口,但没有建立任何连接。 在服务器上运行“npm启动”后,我得到: 服务器侦听0.0.0.0:3000 就这些,问题出在哪里? 代码在本地服务器上运行良好,建立了连接并发送了数据包,但当我尝试在repl.com上运行它时,什么也没有发生

const _ = require('lodash');
const dgram = require('dgram');
const server = dgram.createSocket('udp4');


const serverConfig = {
    welcome: 'Welcome to the game!',
    serverPort: 3000,       //heroku server port!
    clientPort: 6510,
    sendingInterval: 500, //msec
    inactivityCheckInterval: 30, //sec
    pingAfter: 60, //sec
    deactivateAfter: 150, //sec
    debug: true
}

const users = [];
const messages = [];
const outerQueue = [];
const gameSlots = [0,0,0,0,0,0,0,0];
const gameSlotsNumber = [2,2,2,4,4,4,6,6];

const scheduleQueue = () => setTimeout(processQueue, serverConfig.sendingInterval);

const debug = txt => { if (serverConfig.debug) console.log(txt) };


const processQueue = () => {
    if (outerQueue.length > 0) {
        const m = outerQueue.shift();
        //console.log(m);
        server.send(m.body, m.port, m.address, scheduleQueue);
    } else {
        scheduleQueue();
    }
}

const setName = (rinfo, name) => {
    debug(`Auth request from ${rinfo.address}:${rinfo.port}`);
    if (nameInUse(name)) {
        addToQueue(`<M${String.fromCharCode(0)} >** Name in use. Type /nick to set new one`, rinfo.port, rinfo.address);
    } else {
        addToQueue(`<M${String.fromCharCode(1)} >** Authorization OK`, rinfo.port, rinfo.address);
        addToQueue(`<A  >${name}`, rinfo.port, rinfo.address);
        const user = getUser(rinfo);
        if (user) {
            user.name = name;
            registerUserAction(user);
            debug(`Name updated`);
        } else {
            const gmSlot = 20;  //out of regular 8 slots
            users.push({
                address: rinfo.address,
                port: rinfo.port,
                name: name,
                lastAction: nowStamp(),
                gameSlot: gmSlot, 
                active: true
            })
            debug(`User Added`);
        }        
        broadcastStatus();
    }
}


const parseDatagram = (msg, rinfo) => {
    msg = msg || '';
    const header = getHeader(msg);
    if (validateHeader(header)) {
        switch (header.command) {
            case 'S':  // status
                sendStatus(rinfo);
            break;
            case 'A':  // auth
                setName(rinfo, header.body);
            break;
            case 'M':  // message
                sendMessage(rinfo, header);
            break;
//            case 'C':  // command
//                runCommand(rinfo, header);
//            break;
            case 'P':  // ping
                const user = getUser(rinfo);
                if (user) registerUserAction(user);
            break;
            case 'O':                               //set gameslot of the user
                setUserSlot(rinfo,header.body);     //first byte of the message is the number of the slot
                checkForFullSlots(rinfo);
                broadcastUsersInSlots();
            break;          
            case 'X':                               //player lost the battle
                const user2 = getUser(rinfo);
                playerLost(rinfo,user2);        //first byte of the message is the number of the slot
            break;
            case 'Q':                               //lost player quit the game
                const user3 = getUser(rinfo);
                playerQuitGame(user3);
            break;                                  
        }
    } else {
        debug(`Invalid header: ${msg} from ${rinfo.address}:${rinfo.port}`);
    }
}


const sendStatus = rinfo => {
    debug(`Status request from ${rinfo.address}:${rinfo.port}`);
    const user = getUser(rinfo);
    addToQueue(`<S${String.fromCharCode(user && user.active?1:0)}${String.fromCharCode(getActive().length)}>${serverConfig.welcome}`, rinfo.port, rinfo.address);
    if (user && user.active)
        addToQueue(`<A  >${user.name}`, rinfo.port, rinfo.address);
}

const sendMessage = (rinfo, header) => {
    debug(`Message from ${rinfo.address}:${rinfo.port}: ${header.body}`);
    const user = getUser(rinfo);
    if (user) {
        broadcast(`<M  ><${user.name}>${header.body}`);
        registerUserAction(user);
        debug(`Message broadcasted`);
    } else {
        addToQueue(`<M  >** Unauthorized. Type /nick to set name.`, rinfo.port, rinfo.address);
    }
}

const setUserSlot = (rinfo,slotAndUser) => {
    const user = getUser(rinfo)
    if(user){
    user.gameSlot = slotAndUser.msg[5]; //after 4 byte header
    }
    
}

const broadcast = msg => {
    _.each(users, user => {
        if (user.active) {
            addToQueue(`${msg}`, user.port, user.address);
        }
    });
}

const playerQuitGame = (user) => {
    if(user){
    user.gameSlot = 20; //after 4 byte header
    }   
    broadcastUsersInSlots();
}

const playerLost = (rinfo,msx,user) => {
    if(user){
        _.each(users,usr => {
        if(user.gamePort == usr.gamePort)   addToQueue(`<X  >${user.name}`, usr.port, usr.address);
        });         
    }
    
}

const addToQueue = (bodyy, portt, addresss) => outerQueue.push({body:bodyy, port: serverConfig.clientPort,address: addresss});

const checkForFullSlots = (rinfo) => {
        countSlots();
        for(var x=0;x<8;x++){
            if(gameSlots[x]==gameSlotsNumber[x]){
            broadcastBegin(x);      //B->begin the game in the slot     
            }
            
        }
}

const countSlots = () => {
    const slots = [0,0,0,0,0,0,0,0];
        _.each(users, user => {
            if(user.gameSlot<8)         //number f slots equals 8;
            slots[user.gameSlot]++;
        });
        gameSlots = slots;  
    
}
const broadcastBegin = slot => {
    _.each(users, user => {
        if(user.active && user.gameSlot== slot) {
            addToQueue(`<B  >game started, place your ships!`, user.port, user.address);
        }
    });
}   


const getHeader = msg => {
    const msg8 = Uint8Array.from(msg)
    return {
        h1: String.fromCharCode(msg[0]),  //"<"
        command: String.fromCharCode(msg[1]),
        paramL: msg8[2],
        paramH: msg8[3],
        h2: String.fromCharCode(msg[4]), //">"
        body: msg.toString().substring(5)
    }
}
const validateHeader = header => {
    return (header.h1 == '<') && (header.h2 == '>')
}

const getUser = rinfo => _.find(users, {'address': rinfo.address});

const getActive = () => _.filter(users, {'active': true});


const broadcastUsersInSlots = () => {
    
    var usersNames = ["","","","","","","",""];
    for(var i=0;i<8;i++){
        _.each(users, user => {
            if(user.gameSlot == i){
                usersNames[i]+=user.name+"|||";
            }
        });
    }
    _.each(users, user => {
        if (user.active && user.gameSlot <8) {
        var msx = usersNames[user.gameSlot];
            if(msx==""){
                msx="empty";
            }
            addToQueue(`<Y  >${msx}`, user.port, user.address);         //Y equals total users in slots
        }
    });
    broadcastGameSlots();   
}

const broadcastGameSlots = () => {
        _.each(users, user => {
            if(user.active && user.gameSlot > 7) {
            addToQueue(`<W  >${gameSlots[0]}${gameSlots[1]}${gameSlots[2]}${gameSlots[3]}${gameSlots[4]}${gameSlots[5]}${gameSlots[6]}${gameSlots[7]}`,
            user.port,user.address);
            }
        }); 
}
const broadcastShipsUser = (rinfo,userSending,msx) => {
    
    _.each(users, user => {
        if(userSending.gameSlot == user.gameSlot){
            addToQueue(`<Z  >${msx.body}`, user.port, user.address);    //Z equals new ships set by the user, 2 bytes-X,Y pos, 3rd byte-rotation
        }
        
    });
                userSending.status = 1; //ships have been set
}

const broadcastShot = (userSending, msx) => {           // msx contains 2 bytes: x position of the bullet, y position of the bullet
    _.each(users, user => {
        if(userSending.gameSlot == user.gameSlot){
        addToQueue(`<R  >${userSending.name}|||${msx}`,user.port,user.address); 
        }
    });
    
}

const broadcastStatus = msg => {
    _.each(users, user => {
        if (user.active) {
            addToQueue(`<S ${String.fromCharCode(getActive().length)}>`, user.port, user.address);
        }
    });
}

const traceInactivity = () => {
    const now = nowStamp();
    _.each(users, user => {
        if  (user.active) {
            if (now - user.lastAction > serverConfig.pingAfter) {
                pingUser(user);
            };
            if (now - user.lastAction > serverConfig.deactivateAfter) {
                registerUserAction(user, false);
                user.gameSlot= 20;
                broadcastUsersInSlots();
                debug(`deactivated user ${user.name}`);
                broadcastStatus();
            };
        };
    });
    setTimeout(traceInactivity, serverConfig.inactivityCheckInterval * 1000);
}

const pingUser = user => {
    debug(`Pinging user: ${user.name}`);
    addToQueue(`<P  >PING!`, user.port, user.address);
}

const nameInUse = name => _.find(users, {'name': name, 'active': true});


const registerUserAction = (user, active = true) => {
    user.lastAction = nowStamp();
    user.active = active;
}

const nowStamp = () => Math.floor(Date.now() / 1000);

server.on('error', (err) => {
    console.log(`server error:\n${err.stack}`);
    server.close();
});

server.on('message', (msg, rinfo) => {
    debug(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
    parseDatagram(msg, rinfo);
});

server.on('listening', () => {
    const address = server.address();
    console.log(`server listening ${address.address}:${address.port}`);
});

server.bind(serverConfig.serverPort);

scheduleQueue();
traceInactivity();
const=require('lodash');
const dgram=require('dgram');
const server=dgram.createSocket('udp4');
常量服务器配置={
欢迎:'欢迎参加比赛!',
serverPort:3000,//heroku服务器端口!
客户端口:6510,
发送间隔:500,//毫秒
inactivityCheckInterval:30,//秒
pingAfter:60,//秒
停用时间:150,//秒
调试:正确
}
常量用户=[];
常量消息=[];
常量outerQueue=[];
常量游戏槽=[0,0,0,0,0,0,0,0];
常数gameSlotsNumber=[2,2,2,4,4,6,6];
const scheduleQueue=()=>setTimeout(processQueue,serverConfig.SendinInterval);
const debug=txt=>{if(serverConfig.debug)console.log(txt)};
const processQueue=()=>{
如果(outerQueue.length>0){
const m=outerQueue.shift();
//控制台日志(m);
发送(m.body、m.port、m.address、scheduleQueue);
}否则{
scheduleQueue();
}
}
const setName=(rinfo,name)=>{
调试(`Auth request from${rinfo.address}:${rinfo.port}`);
如果(名称使用(名称)){
addToQueue(`**Name in use.Type/nick设置新的`,rinfo.port,rinfo.address);
}否则{
addToQueue(`**Authorization OK`,rinfo.port,rinfo.address);
addToQueue(`${name}`,rinfo.port,rinfo.address);
const user=getUser(rinfo);
如果(用户){
user.name=名称;
注册操作(用户);
调试(`Name updated`);
}否则{
const gmSlot=20;//在常规的8个插槽中
用户推送({
地址:rinfo.address,
港口:rinfo.port,
姓名:姓名,,
lastAction:nowStamp(),
游戏槽:gmSlot,
主动:正确
})
调试(`User Added`);
}        
广播状态();
}
}
const parseDatagram=(msg,rinfo)=>{
味精=味精| |'';
const header=getHeader(msg);
if(验证标题(标题)){
开关(header.command){
案例'S'://状态
发送状态(rinfo);
打破
案例“A”://auth
setName(rinfo,header.body);
打破
大小写'M'://消息
sendMessage(rinfo,header);
打破
//案例'C'://命令
//runCommand(rinfo,header);
//中断;
案例'P'://ping
const user=getUser(rinfo);
如果(用户)注册操作(用户);
打破
案例'O'://设置用户的游戏槽
setUserSlot(rinfo,header.body);//消息的第一个字节是插槽的编号
检查完整插槽(rinfo);
broadcastUsersInSlots();
打破
案例'X'://玩家输掉了这场战斗
constuser2=getUser(rinfo);
playerLost(rinfo,user2);//消息的第一个字节是插槽的编号
打破
案例'Q'://输了的玩家退出游戏
const user3=getUser(rinfo);
玩家退出游戏(用户3);
打破
}
}否则{
调试(`Invalid header:${msg}来自${rinfo.address}:${rinfo.port}`);
}
}
const sendStatus=rinfo=>{
调试(`Status request from${rinfo.address}:${rinfo.port}`);
const user=getUser(rinfo);
addToQueue(`${serverConfig.welcome}`,rinfo.port,rinfo.address);
if(user&&user.active)
addToQueue(`${user.name}`,rinfo.port,rinfo.address);
}
const sendMessage=(rinfo,header)=>{
调试(`messagefrom${rinfo.address}:${rinfo.port}:${header.body}`);
const user=getUser(rinfo);
如果(用户){
广播(`${header.body}`);
注册操作(用户);
调试(`messagebroadcasted`);
}否则{
addToQueue(`**Unauthorized.Type/nick设置名称,`,rinfo.port,rinfo.address);
}
}
const setUserSlot=(rinfo,slotAndUser)=>{
const user=getUser(rinfo)
如果(用户){
user.gameSlot=slotAndUser.msg[5];//在4字节头之后
}
}
const broadcast=msg=>{
_.each(用户,用户=>{
if(user.active){
addToQueue(`${msg}`,user.port,user.address);
}
});
}
const playerQuitGame=(用户)=>{
如果(用户){
user.gameSlot=20;//在4字节头之后
}   
broadcastUsersInSlots();
}
常量playerLost=(rinfo、msx、用户)=>{
如果(用户){
_.每个(用户,usr=>{
if(user.gamePort==usr.gamePort)addToQueue(`${user.name}`,usr.port,usr.address);
});         
}
}
const addToQueue=(body,portt,addresss)=>outerQueue.push({body:body,port:serverConfig.clientPort,address:addresss});
const checkForFullSlots=(rinfo)=>{
countSlots();
对于(var x=0;xbegin)在老虎机中开始游戏
}
}
}
常量countSlots=()=>{
常量插槽=[0,0,0,0,0,0,0,0];
_.each(用户,用户=>{
如果(user.gameSlot{
_.each(用户,用户=>{
if(user.active&&user.gameSlot==slot){
addToQueue(`game started,place your ships!`,user.port,user.address);
}
});
}   
const getHeader=msg=>{
常量msg8=Uint8Array.from(msg)
返回{
h1:String.fromCharCode(消息[0]),/“”
正文:msg.toString