[Android +MySQL] 채팅

LeeEunJae·2022년 9월 5일
0

Study Kotlin

목록 보기
12/20

📌 실행 결과

위의 실행 결과는 에뮬레이터와 제 갤럭시 탭을 사용해서 채팅 기능 테스트를 한 것입니다.

이전 게시물에서 MySQL 을 사용한 로그인, 회원가입을 구현해봤습니다. 이번에는 기능을 확장하여 채팅을 구현했습니다.

Firebase Realtime Database 를 사용해서 채팅을 구현 하는 것은 많이 해봐서 쉬운데 Firebase 를 사용하지 않고, MySQL 로 구현하려니 꽤 어려웠다... 왜냐하면, 안드로이드에서 보안문제 때문에 MySQL 과 직접 연동이 불가능해서 서버를 따로 만들고, 서버와의 통신으로 MySQL에 접근해야하기 때문이다.

우여곡절 끝에 MySQL 을 연동해서 데이터를 삽입하고, 불러오는 것 까지 완료했지만, 한가지 고려해야할 문제점이 있었다.
상대방이 채팅을 보냈을 때 안드로이드에서 그 신호를 받고 즉각적으로 채팅을 보여줘야하는데 MySQL 에는 그런 Listener 기능이 없다.

그래서 생각해낸 방법은 소켓통신을 통해 채팅을 하고, 로그인, 회원가입, 채팅목록 불러오기, 채팅 저장 등 같은 기능들은 MySQL 로 구현하는 것이다.
이 방법이 맞는 방법인지는 잘 모르겠지만, 아무튼 난 이렇게 구현했다
방법이 어찌됐던 MySQL, 소켓통신, Node.js공부를 한꺼번에 할 수 있으니 그걸로 만족한다

📌 데이터베이스 구조

  1. 유저
  1. 채팅방
  1. 메시지

📌 Node.js 서버

get, post 요청에 대한 부분의 작업을 처리하는 부분

const mysql = require('mysql2');
const dbconfig = require('../config/database.js');
const connection = mysql.createConnection(dbconfig);
var express = require('express');
var router = express.Router();
const bodyParser = require('body-parser');    // 1
router.use(bodyParser.urlencoded({ extended: true }));    // 2

router.post('/position', (request, response)=>{
	response.json(request.body); // or response.send(request.body);
});

router.get('/', function(req, res, next) {
  res.status(200).json(
    {
      "success" : true
    }
  );
});

router.get('/users_info', (req, res) => {
  connection.query('SELECT * FROM User', (error, rows) => {
    if(error) throw error;
    console.log('user info is : ', rows);
    
    res.status(200).send(rows)
    
  });
});

router.post('/getUserId', (req, res)=>{
  const uid = req.body.UID

  connection.query('select id from User where UID=?',[uid], (err,rows)=>{
    if(err) throw err
    console.log('user info is : ', rows)
    res.status(200).send(rows)
  })
})

router.post('/login', (req, res)=>{
  const body = req.body;
  const id = body.id;
  const pw = body.pw;

  connection.query('select * from User where id=? and password=?', [id,pw], (err, data)=>{
    if(data.length == 0){ // 로그인 실패
      console.log('로그인 실패');
      res.status(200).json(
        {
          "UID" : -1
        }
      )
    }
    else{
      // 로그인 성공
      console.log('로그인 성공');
      connection.query('select UID from User where id=?',[id],(err,data)=>{
        res.status(200).send(data[0]); 
      });
      
    }
  });
});


router.post('/register', (req, res) =>{
  const body = req.body;
  const id = body.id;
  const pw = body.pw;

  connection.query('select * from User where id=?',[id],(err,data)=>{
    if(data.length == 0){
        console.log('회원가입 성공');
        connection.query('insert into User(id, password) values(?,?)',[id,pw]);
        res.status(200).json(
          {
            "message" : true
          }
        );
    }else{
        console.log('회원가입 실패');
        res.status(200).json(
          {
            "message" : false
          }
        );
        
    }
    
  });
});

router.post('/room', (req,res)=>{
  const body = req.body;
  const sender_id = body.sender_id;
  const receiver_id = body.receiver_id;

  connection.query('select * from Room where (sender_id=? and receiver_id=?) or (sender_id=? and receiver_id=?)',[sender_id,receiver_id,receiver_id,sender_id],(err,data)=>{
    if(data.length==0){
      // 만들어진 채팅방이 없으므로 생성
      connection.query('insert into Room(sender_id, receiver_id) values(?,?)',[sender_id,receiver_id]);
      res.status(200).json(
        {
          "message" : true
        }
      )

    }else{
      // 이미 채팅방이 존재함
      res.status(200).json({
        "message" : false
      })
    }
  });
});

router.post('/message', (req,res)=>{
  const body = req.body;
  const sender_id = body.sender_id;
  const receiver_id = body.receiver_id;
  const text = body.text;
  const time = body.time;

  connection.query('insert into message(sender_id, receiver_id, text, time) values(?,?,?,?)',[sender_id,receiver_id,text,time]);
  console.log(text);
  res.send(req.body);

});

router.post('/getMessage', (req,res)=>{
  const body = req.body;
  const sender_id = body.sender_id;
  const receiver_id = body.receiver_id;

  connection.query('select sender_id, receiver_id, text, time from message where (sender_id = ? and receiver_id = ?) or (sender_id = ? and receiver_id = ?)',[sender_id,receiver_id,receiver_id,sender_id],(error,rows)=>{
    if(error) throw error;
    console.log('user info is : ', rows);
    
    res.status(200).send(rows)
  });
});

router.post('/getAllRoom', (req,res)=>{
  const sender_id = req.body.sender_id;

  connection.query('select * from Room where sender_id=?',[sender_id],(error,rows)=>{
    if(error) throw error;
    console.log('user info is : ', rows);
    
    res.status(200).send(rows)
  });
})

router.post('/getRoom', (req,res)=>{
  const body = req.body;
  const sender_id = body.sender_id;
  const receiver_id = body.receiver_id;
  
  connection.query('select number from Room where (sender_id=? and receiver_id=?) or (sender_id=? and receiver_id=?) ',[sender_id,receiver_id,receiver_id,sender_id],(error,rows)=>{
    if(error) throw error;
    console.log('user info is : ', rows);
    
    res.status(200).send(rows)
  });
})


module.exports = router;

소켓통신을 담당하는 부분

socket.on('eventName', function(data)) 를 통해 클라이언트가 eventName 이라는 이벤트를 발생시키고 data 를 전달하면 중괄호 안에서 작업을 수행하고 io.emit() 을 통해 클라이언트에게 응답을 보낸다.

var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
const bodyParser = require('body-parser');    // 1
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }));    // 2

io.on('connection', (socket) => {
  console.log("user connect");

  socket.on('connectReceive', (data) => {
  	console.log(data)
  });

  socket.on('disconnect', function() {
  console.log('user disconnected');
  });

  socket.on('connect user', function(user){
    console.log("Connected user ");
    socket.join(user['roomNumber']);
    console.log("roomNumber : ",user['roomNumber']);
    console.log("state : ",socket.adapter.rooms);
    io.emit('connect user', user);
  });
    //메세지 입력하면 서버 로그에 이거뜸
  socket.on('chat message', function(msg){
    console.log("Message " + msg['text']);
    console.log("보내는 아이디 : ",msg['sender_id']);
    console.log("방 번호 : ", msg['roomNumber'])
    io.to(msg['roomNumber']).emit('chat message', msg);
  });
  
});

app.use('/', require('./routes/rides'));


server.listen(8080, function(){
  console.log("server on 8080");
});

다음 게시물에서 안드로이드와 연동하는 방법에 대해서 다루겠습니다.

profile
매일 조금씩이라도 성장하자

0개의 댓글