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