• 로그인
  • 장바구니에 상품이 없습니다.

home2 게시판 Node.js, Express 게시판 유저간 채팅기능 도배에러

유저간 채팅기능 도배에러

2 글 보임 - 1 에서 2 까지 (총 2 중에서)
  • 글쓴이
  • #54215

    이창민
    참가자
    선생님 채팅이 도배가 되는 에러가 나타납니다. ㅠㅠ
    1. 유저1로 로그인 후 list에서 유저2가 발행한 게시물의 채팅버튼 누름
    2. chat페이지에서 유저2와 채팅룸 클릭후 1번째메시지를 입력후 전송누름  <- 정상적으로 1개만 db에 저장되고 출력됨
    3. 2번째메시지를 입력후 전송누름  <- 채팅창에는 2번째메시지가 2번출력되고, db상에서는 같은내용이 3번저장됨
    
    server.js-----------------------------------
    const express = require('express');
    const app = express();
    app.use(express.static("views"));
    const bodyParser = require('body-parser');
    const { render } = require('express/lib/response');
    app.use(bodyParser.urlencoded({extended : true}));
    const MongoClient = require('mongodb').MongoClient;
    const methodOverride = require('method-override')
    app.use(methodOverride('_method'))
    const passport = require('passport');
    const LocalStrategy = require('passport-local').Strategy;
    const session = require('express-session');
    // const { objectId } = require('mongodb')
    app.use(session({secret : '비밀코드', resave : true, saveUninitialized: false}));
    app.use(passport.initialize());
    app.use(passport.session()); 
    app.set('view engine', 'ejs');
     
    var db;
    MongoClient.connect('mongodb+srv://2ckdaks:@cluster0.0qiowcf.mongodb.net/?retryWrites=true&w=majority', function(에러, client){
    if (에러) return console.log(에러)
    db = client.db('todoapp');
    //저장은 object형식으로
    // db.collection('post').insertOne( {이름 : 'John', 나이 : 20, _id : 100}, function(에러, 결과){
    // console.log('저장완료')
    // });
    app.listen(8080, function(){
    console.log('위이이이잉 mongoDB연결 완료')
     })
    });
    //html 파일 연결
    app.get('/', function(요청, 응답){
    응답.render('index.ejs')
    })
    app.get('/write', function(요청, 응답) { 
    응답.render('write.ejs')
     });
    //저장된 데이터 보여주는 페이지
    app.get('/list', function(요청, 응답){
    db.collection('post').find().toArray(function(에러, 결과){
    응답.render('list.ejs', { posts : 결과});
     });
    });
    //상세페이지 링크
    app.get('/detail/:id', function(요청, 응답){
    db.collection('post').findOne({_id : parseInt(요청.params.id)}, function(에러, 결과){
    응답.render('detail.ejs',{data : 결과})
     })
    })
    //edit페이지 해당상품 불러오기
    app.get('/edit/:id', function(요청, 응답){
    db.collection('post').findOne({_id : parseInt(요청.params.id)}, function(에러, 결과){
    응답.render('edit.ejs', {post : 결과 })
     })
    })
    //edit페이지로 폼 전송
    app.put('/edit', function(요청, 응답){
    db.collection('post').updateOne({_id : parseInt(요청.body.id)}, { $set : {제목 : 요청.body.title, 날짜 : 요청.body.date }}, function(에러, 결과){
    console.log('수정완료')
    응답.redirect('/list')
     })
    })
    app.get('/login', function(req, res){
    res.render('login.ejs')
    })
    app.post('/login', passport.authenticate('local', {
    failureRedirect : '/fail'
    }), function(req, res){
    res.redirect('/')
    })
    //회원페이지
    passport.use(new LocalStrategy({
    usernameField: 'id',
    passwordField: 'pw',
    session: true,
    passReqToCallback: false,
     }, function (입력한아이디, 입력한비번, done) {
    //console.log(입력한아이디, 입력한비번);
    db.collection('login').findOne({ id: 입력한아이디 }, function (에러, 결과) {
    if (에러) return done(에러)
    if (!결과) return done(null, false, { message: '존재하지않는 아이디요' })
    if (입력한비번 == 결과.pw) {
    return done(null, 결과)
     } else {
    return done(null, false, { message: '비번틀렸어요' })
     }
     })
     }));
    passport.serializeUser(function (user, done) {
    done(null, user.id)
     });
     
    passport.deserializeUser(function (아이디, done) {
    db.collection('login').findOne({ id: 아이디 }, function (에러, 결과) {
    done(null, 결과)
     })
     });
    app.post('/register', function (요청, 응답) {
    db.collection('login').insertOne({ id: 요청.body.id, pw: 요청.body.pw }, function (에러, 결과) {
    응답.redirect('/')
     })
     })
    //마이페이지로 요청을했을때 미들함수 저 로그인했니를 거치면
    app.get('/mypage', 로그인했니, function (요청, 응답) {
    응답.render('mypage.ejs', { 사용자 : 요청.user}) 
     })
    function 로그인했니(요청, 응답, next) { 
    if (요청.user) { 
    next() 
     } 
    else { 
    응답.send('로그인안하셨는데요?') 
     } 
     }
    //hw 어떤사람이 /add라는 경로로 post 요청을 하면,
    //데이터 2개(날짜, 제목)을 보내주는데,
    //이때, 'post'라는 이름을 가진 collection에 두개 데이터를 저장하기
    app.post('/add', function(요청, 응답){
    응답.send('전송완료');
    db.collection('counter').findOne({name : '게시물갯수'}, function(에러, 결과){
    var 총게시물갯수 = 결과.totalPost;
    var 저장할거 = { _id : 총게시물갯수 +1, 제목 : 요청.body.title, 날짜 : 요청.body.date, 작성자 : 요청.user.id }
    db.collection('post').insertOne(저장할거, function(에러, 결과){
    console.log('저장완료')
    db.collection('counter').updateOne({name : '게시물갯수'},{ $inc : {totalPost : 1}}, function(에러, 결과){
    if(에러){return console.log(에러)}
    else{console.log(결과)}
     })
     });
     });
     })
    //데이터 삭제 요청
    app.delete('/delete', function (요청, 응답) {
    요청.body._id = parseInt(요청.body._id);
    db.collection('post').deleteOne({id : 요청.body.id, 작성자 : 요청.user.id }, function (에러, 결과) {
    console.log('삭제완료');
    응답.status(200).send({ message: '성공했습니다' });
     })
    });
    //검색기능
    app.get('/serch', (요청, 응답)=> {
    // console.log(요청.query)
    var 검색조건 = [
     {
    $search: {
    index: 'titleSearch',
    text: {
    query: 요청.query.value,
    path: '제목' // 제목날짜 둘다 찾고 싶으면 ['제목', '날짜']
     }
     }
     },
     { $sort : { _id : 1 } },
     { $limit : 10 }, // 상위 몇개만 보여줄지
    // { $project : { 제목 : 1, _id : 0 } }
     ] 
    db.collection('post').aggregate(검색조건).toArray((에러, 결과)=>{
    console.log(결과)
    응답.render('serch.ejs', {posts : 결과})
     })
     })
     
    app.use('/shop', require('./routes/shop.js') );
    //route들 관리
    // app.get('/shop/shirts', function(요청, 응답){
    // 응답.send('셔츠 파는 페이지입니다.');
    // });
     
    // app.get('/shop/pants', function(요청, 응답){
    // 응답.send('바지 파는 페이지입니다.');
    // });
    app.use('/board/sub', require('./routes/board.js'));
     
    //이미지 업로드
    let multer = require('multer');
    var storage = multer.diskStorage({
    destination : function(req, file, cb){
    cb(null, './public/image')
     },
    filename : function(req, file, cb){
    cb(null, file.originalname )
     }
    });
    var upload = multer({storage : storage});
    app.get('/upload', function(요청, 응답){
    응답.render('upload.ejs')
    })
    app.post('/upload', upload.single('profile'), function(요청, 응답){
    응답.send('업로드완료')
    });
    app.get('/image/:imageName', function(요청, 응답){
    응답.sendFile( __dirname + '/public/image/' + 요청.params.imageName )
    })
    //chat
    app.post('/chatroom', 로그인했니, function(요청, 응답){
    var 저장할거 = {
    title : '무슨무슨채팅방',
    member : [요청.body.당한사람id, 요청.user._id],
    date : new Date()
     }
    db.collection('chatroom').insertOne(저장할거).then(function(결과){
    응답.send('저장완료')
     });
    });
    app.get('/chat', 로그인했니, function(요청, 응답){
    db.collection('chatroom').find().toArray({member : 요청.user._id}).then(function(결과){
    응답.render('chat.ejs', { data : 결과 })
     })
    })
    app.post('/message', 로그인했니, function(요청, 응답){
    var 저장할거 = {
    parent : 요청.body.parent,
    content : 요청.body.content,
    userid: 요청.user.id,
    date : new Date()
     }
    db.collection('message').insertOne(저장할거).then((결과)=>{
    console.log('db저장 성공')
    응답.send(결과)
     }).catch(()=>{
    console.log('시발')
     })
    });
    app.get('/message/:id', 로그인했니, function(요청, 응답){
    응답.writeHead(200, {
    "Connection": "keep-alive",
    "Content-Type": "text/event-stream",
    "Cache-Control": "no-cache",
     });
    db.collection('message').find({ parent : 요청.params.id}).toArray().then((결과)=>{
    응답.write('event: test\n');
    응답.write('data: ' + JSON.stringify(결과) +'\n\n');
     })
     
    const 찾을문서 = [
     { $match: { 'fullDocument.parent' : 요청.params.id } }
     ];
     
    const changeStream = db.collection('message').watch(찾을문서);
    changeStream.on('change', (result) => {
    응답.write('event: test\n');
    응답.write('data: ' + JSON.stringify([result.fullDocument]) +'\n\n');
     });
    });
    
    
    
    chat.ejs----------------------------------
    <!doctype html>
    <html>
    <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
    <link rel="stylesheet" href="chat.css">
    <title>Hello, world!</title>
    </head>
    <body>
    <%- include('nav.html') %>
    <div class="container p-4 detail">
    <div class="row">
    <div class="col-3">
    <ul class="list-group chat-list">
    <% for (let i = 0; i < data.length; i++){ %>
    <li class="list-group-item" data-id="<%= data[i]._id %>">
    <h6><%= data[i].title %></h6>
    <h6 class="text-small"><%= data[i].member[0] %></h6>

    <% } %>

    </div>   <div class="col-9 p-0"> <div class="chat-room"> <ul class="list-group chat-content">

     

    • <span class="chat-box"></span>

     

     

     

    • <span class="chat-box"></span>

     

     

     

    • <span class="chat-box mine"></span>

     

    <div class="input-group"> <input class="form-control" id="chat-input"> <button class="btn btn-secondary" id="send">전송</button> </div> </div> </div> </div> </div>

    <script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script>
    <script>
    var eventSource;
    $('.list-group-item').click(function(){
    var 지금누른채팅방id = this.dataset.id;
    $('.chat-content').html('');
    if(eventSource != undefined){
    eventSource.close()
     }
    eventSource = new EventSource('/message/' + 지금누른채팅방id);
    eventSource.addEventListener('test', function(e){
    var 가져온거 = JSON.parse(e.data);
    가져온거.forEach(function(i){
    $('.chat-content').append('
    • <span class="chat-box">' + i.content + ' </span>

    ') }) })

    $('#send').click(function(){
    var 채팅내용 = $('#chat-input').val();
    var 보낼거 = {
    parent : 지금누른채팅방id,
    content : 채팅내용,
     }
    $.post('/message', 보낼거).then(()=>{
    console.log('전송성공')
     })
     })
     })
     
    </script>
    </body>
    </html>
    
    
    		
    	
    #54250

    codingapple
    키 마스터
    이벤트버블링현상때문에 채팅방 클릭시 여러번 클릭될텐데 아마 뒤 강의에 나올걸요
2 글 보임 - 1 에서 2 까지 (총 2 중에서)
  • 답변은 로그인 후 가능합니다.

About

현재 월 700명 신규수강중입니다.

  (09:00~20:00) 빠른 상담은 카톡 플러스친구 코딩애플 (링크)
  admin@codingapple.com
  이용약관, 개인정보처리방침
ⓒ Codingapple, 강의 예제, 영상 복제 금지
top

© Codingapple, All rights reserved. 슈퍼로켓 에듀케이션 / 서울특별시 강동구 고덕로 19길 30 / 사업자등록번호 : 212-26-14752 온라인 교육학원업 / 통신판매업신고번호 : 제 2017-서울강동-0002 호 / 개인정보관리자 : 박종흠