인프런 커뮤니티 질문&답변

rlawjddn4706님의 프로필 이미지
rlawjddn4706

작성한 질문수

[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지

redis 사용하는데 ConnectionTimeoutError: Connection timeout이라는 오류가 자꾸 발생합니다.

해결된 질문

작성

·

2K

0

안녕하세요 강사님

강사님 영상을 통해 학습하고 자그마한 프로젝트를 수행하고 있는데 서버 실행은 되지만 아래와 같은 오류가 발생합니다.

app.js의 코드는 아래와 같습니다.

강의랑 ppt 교안에는 const RedisStore = require('connect-redis')(sesson); 으로 되어있으나

저같은 경우에 아래와 같은 오류가 발생해서 require('connect-redis').default;로 변경했었습니다.

답변 1

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

레디스 연결이 안된 건데요. 레디스 aws에 만드셨나요??

소스코드는 깃헙 소스코드가 최신입니다

rlawjddn4706님의 프로필 이미지
rlawjddn4706
질문자

영상 따라서

redis 사이트에 들어가서 만들었습니다.

image

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

redisClient 밑에 코드 더 적으셨나요?

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

제 강좌랑 버전을 똑같이하시거나, 최신코드면 코드 업데이트하셔야합니다.

https://github.com/ZeroCho/nodejs-book/issues/348

 

rlawjddn4706님의 프로필 이미지
rlawjddn4706
질문자

네 강사님 아래와 같이 적었습니다.

const express = require('express');
const cookieParser = require('cookie-parser');
const morgan = require('morgan');
const path = require('path');
const session = require('express-session');
const nunjucks = require('nunjucks');
const dotenv = require('dotenv');
const passport = require('passport');
const helmet = require('helmet');
const hpp = require('hpp');
const RedisStore = require('connect-redis').default;
const redis = require('redis');
const cors = require('cors');

// process.env.COOKIE_SECRET 없음
dotenv.config(); // process.env
// process.env.COOKIE_SECRET 있음
const redisClient = redis.createClient({
    url: `redis://${process.env.REDIS_HOST}:${process.env.REDIS_PORT}`,
    password: process.env.REDIS_PASSWORD,
    legacyMode: true
});
redisClient.connect().catch(console.error);
const pageRouter = require('./routes/page');
const authRouter = require('./routes/auth');
const postRouter = require('./routes/post');
const userRouter = require('./routes/user');
const machineRouter = require('./routes/machine');
const { sequelize } = require('./models');
const passportConfig = require('./passport');
const logger = require('./logger');

const app = express();
passportConfig(); // 패스포트 설정
app.set('port', process.env.PORT || 8003);
app.set('view engine', 'html');
nunjucks.configure('views', {
    express: app,
    watch: true,
});

sequelize.sync({ force: false })    // 개발시 테이블 잘못 만들었다면 force: true로, 다시 만들어줌 (배포시에는 금지!)
    .then(() => {
        console.log('데이터베이스 연결 성공');
    })
    .catch((err) => {
        console.error(err);
    });

if (process.env.NODE_ENV === 'production') {
    app.enable('trust proxy'); // proxy server를 사용한다면 넣어주면 좋음
    app.use(morgan('combined'));
    app.use(
        helment({
            contentSecurityPolicy: false,
            crossOriginEmbedderPolicy: false,
            crossOriginResourcePolicy: false,
        }),
    );
    app.use(hpp());
    app.use(cors({
        origin: 'http://project.com',   // 나중에 배포시 도메인
        credentials: true,
    }));
} else {
    app.use(morgan('dev'));
    app.use(cors({
        origin: ['http://localhost:8080', 'http://localhost:8003'],
        credentials: true
    }));
}

app.use(morgan('dev')); // 개발할 때는 자세한 dev로, 배포시 combined으로 바꾸는 거 추천
app.use(express.static(path.join(__dirname, 'public'))); // __dirname(app.js가 있는 폴더 toyproject-sns를 가리킴). 그 안의 public 폴더를 가져오라는 의미
app.use('/img', express.static(path.join(__dirname, 'uploads'))); // front에서 img를 가져오기 위함
app.use(express.json());    // req.body를 ajax json 요청으로부터
app.use(express.urlencoded({ extended: false })); // form양식 요청 허용 (req.body 폼으로부터)
app.use(cookieParser(process.env.COOKIE_SECRET));
const sessionOption = {
    resave: false,
    saveUninitialized: false,
    secret: process.env.COOKIE_SECRET,
    cookie: {
      httpOnly: true,
      secure: false,
    },
    store: new RedisStore({ client: redisClient }),
};
if (process.env.NODE_ENV === 'production') {
sessionOption.proxy = true;
// sessionOption.cookie.secure = true;
}
app.use(session(sessionOption));
app.use(passport.initialize()); // req.user, req.login, req.isAuthenticate, req.logout
app.use(passport.session()); // connect.sid라는 이름으로 세션 쿠키가 브라우저로 전송

app.use('/', pageRouter);
app.use('/auth', authRouter);
app.use('/post', postRouter);
app.use('/user', userRouter);
app.use('/machine', machineRouter);

app.use((req, res, next) => {
    const error = new Error(`${req.method} ${req.url} 라우터가 없습니다.`);
    error.status = 404;
    logger.info('hello');
    logger.error(error.message);
    next(error);
});

// 에러 처리 미들웨어
app.use((err, req, res, next) => {
    console.error(err);
    res.locals.message = err.message;
    res.locals.error = process.env.NODE_ENV !== 'production' ? err : {}; // 배포 모드가 아닐 때 err 넣어줌. 배포 모드면 err 안 넣어줌 --> 배포 시, 에러 로그들은 서비스한테 넘김
    res.status(err.status || 500);
    res.render('error'); // error.html을 nunjucks가 views 폴더에서 찾아서 응답으로 보내줌
});

module.exports = app;
rlawjddn4706님의 프로필 이미지
rlawjddn4706
질문자

저의 package.json dependencies 내용입니다.

강사님 깃허브에는 redis 버전이 "^3.0.2", connect-redis는 "^4.0.4"를 사용하고 계시는데 이걸로 낮춰야할까요??

    "dependencies": {
        "@aws-sdk/client-s3": "^3.377.0",
        "bcrypt": "^5.1.0",
        "connect-redis": "^7.1.0",
        "cookie-parser": "^1.4.6",
        "cors": "^2.8.5",
        "cross-env": "^7.0.3",
        "csurf": "^1.11.0",
        "dotenv": "^16.3.1",
        "express": "^4.18.2",
        "express-session": "^1.17.3",
        "helmet": "^7.0.0",
        "hpp": "^0.2.3",
        "morgan": "^1.10.0",
        "multer": "^1.4.5-lts.1",
        "multer-s3": "^3.0.1",
        "mysql2": "^3.4.2",
        "nunjucks": "^3.2.4",
        "passport": "^0.6.0",
        "passport-kakao": "^1.0.1",
        "passport-local": "^1.0.0",
        "pm2": "^5.3.0",
        "redis": "^4.6.7",
        "sanitize-html": "^2.11.0",
        "sequelize": "^6.32.1",
        "sequelize-cli": "^6.6.1",
        "winston": "^3.10.0"
    },
    "devDependencies": {
        "nodemon": "^2.0.22"
    }
rlawjddn4706님의 프로필 이미지
rlawjddn4706
질문자

버전도 3.0.2, 4.0.4로 바꾸고 강사님 깃헙 코드에 맞춰 변경했는데

아래와 같은 오류가 발생합니다..ㅠㅠ

다른 것들도 버전을 바꿔야하는 걸까요..

image

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

아뇨 제가 올려드린 issue 코드는 최신 버전일 때의 코드입니다.

깃허브에 있는 코드는 책의 버전인거고요.

issue랑 깃허브 코드랑 서로 다른 버전의 코드입니다.

rlawjddn4706님의 프로필 이미지
rlawjddn4706
질문자

넵 감사합니다. 강사님

근데 계속 바로 위 TypeError 오류에서 몇시간째 막히고 있습니다...ㅠㅠ

TypeError는 주로 오타나 변수 중복선언 문제인게 맞는건가요??

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

버전을 최신버전으로 업데이트하신게 맞나요?

rlawjddn4706님의 프로필 이미지
rlawjddn4706
질문자

버전을 낮추는걸로 선택해서 해결했습니다..

redis "^3.0.2", connect-redis는 "^4.0.4"로 버전 설치하고 아래 방식으로 해결하긴 했습니다.

const RedisStore = require('connect-redis')(session);
const redis = require('redis');
const cors = require('cors');

// process.env.COOKIE_SECRET 없음
dotenv.config(); // process.env
// process.env.COOKIE_SECRET 있음
const redisClient = redis.createClient({ 
    url: `redis://${process.env.REDIS_HOST}:${process.env.REDIS_PORT}`,
    password: process.env.REDIS_PASSWORD,
    legacyMode: true,
});
const pageRouter = require('./routes/page');

 

근데 의문인점은

redis랑 connect-redis 버전을 최신껄로(4.6.7, 7.1.0) 설치 후에 issues에 올려주신 코드를 기반으로 실행했을 때는 TypeError가 자꾸 발생했습니다.

const RedisStore = require('connect-redis')(session);
const redis = require('redis');
const cors = require('cors');

// process.env.COOKIE_SECRET 없음
dotenv.config(); // process.env
// process.env.COOKIE_SECRET 있음
const redisClient = redis.createClient({ 
    url: `redis://${process.env.REDIS_HOST}:${process.env.REDIS_PORT}`,
    password: process.env.REDIS_PASSWORD,
    legacyMode: true,
});
redisClient.connect().catch(console.error);
const pageRouter = require('./routes/page');

image

image

나머지 다른 코드들의 변경 사항은 없었습니다.

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

connect-redis 버전이 7로 올라감에 따라 소스코드 수정이 한 번 더 있었네요.

const RedisStore = require('connect-redis').default;

이렇게 바꾸시면 됩니다.

rlawjddn4706님의 프로필 이미지
rlawjddn4706
질문자

제가 맨 처음 질문 게시글 올렸을 때 강사님이 방금 답글로 주신 .default로 바꾸는 방식으로 했었는데

npm run dev로 실행하니 아래와 같은 에러가 떴던 거였습니다.

image

제 생각에는

redisClient.connect().catch(console.error);

connect-redis 버전이 7로 올라가면서 이 부분에도 문제가 있는건 아닌가 라는 생각이 듭니다..

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

테스트해본 결과 문제가 없었습니다

rlawjddn4706님의 프로필 이미지
rlawjddn4706
질문자

앗 그런가요?? 그럼 제 코드 다른쪽에서 문제가 있었던거 같네요..ㅠㅠ

아래 링크에 이분들도 redis를 ^4.6.7버전을 사용할 때 저와 동일한 에러가 발생하길래 혹시나 해서...

다들 최근에 발생했더라구요..ㅠㅠ

https://github.com/redis/node-redis/issues/2550

https://stackoverflow.com/questions/76570448/connectiontimeouterror-connection-timeout-in-redis-6-2-7

감사합니다 강사님

rlawjddn4706님의 프로필 이미지
rlawjddn4706

작성한 질문수

질문하기