티스토리 뷰

728x90
반응형

 

* 내가 작업하고 있는 공간은 프로그래밍을하는 server.js 와 static 폴더에 있는 css, js, html 파일이다.

 

Step01 - php에서 클라이언트가 채팅버튼을 클릭했을 경우와 클라이언트가 메시지를 보내는 경우

        -> server.js

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
const express        = require('express'); //설치한 express 모듈 불러오기
const socket         = require('socket.io'); //설치한 socket.io 모듈 불러오기
const http           = require('http'); //Node.js 기본 내장 모듈 불러오기
const fs             = require('fs'); //Node.js 기본 내장 모듈 불러오기
const app            = express();    // express 객체 생성
const server         = http.createServer(app); //express http 서버 생성
const io             = socket(server); //생성된 서버를 socket.io에 바인딩
var mb_id            = ""// php서버에서 사용자 보내주는 파라미터 - ID값
var mb_name          = ""// php서버에서 사용자 보내주는 파라미터 - 이름값
var admin_mb_id      = ""// php서버에서 관리자 보내주는 파라미터 - ID값
var admin_mb_name    = ""// php서버에서 관리자 보내주는 파라미터 - 이름값
var ip_address       = ""// IP 주소
 
const mysql      = require('mysql');
const connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'xxxx',      //자신의 정보 입력
  password : 'xxxxxxx',   //자신의 정보 입력
  database : 'xxxx'       //자신의 정보 입력
});
 
/* css, js 파일 적용  */
app.use('/css', express.static('./static/css'));
app.use('/js', express.static('./static/js'));
 
 
/* 사용자측면 / 경로에 접속하면 실행 됨 */
app.get('/'function(request, response) {
  mb_id   = request.query.mb_id;
  mb_name = request.query.mb_name;
 
  fs.readFile('./static/index.html'function(err, data) {
    if(err) {
      response.send('에러')
    } else {
      response.writeHead(200, {'Content-Type':'text/html'})
      response.write(data)
      response.end()
    }
  })
});
 
 
// 소켓 연결 
io.sockets.on('connection'function(socket) {
 
  // 아이피 주소
  require('dns').lookup(require('os').hostname(), function (err, add, fam) {
    ip_address = add;
  })
 
  // 사용자 입장
  socket.on('NewUser'function() {
    socket.name = mb_name; // 소켓에 이름 저장해두기
 
    socket.join(mb_id); // User 입장시 Room에 들여보냄
 
    if(mb_id != ""){
      // 사용자 입장시 채팅방에 사용자를 작성
      connection.query('SELECT * FROM chatting_room WHERE mb_id = ?', mb_id ,function(err,result) {
          if(result.length == 0){
              var sql = 'INSERT INTO chatting_room(mb_id, mb_name) VALUES(?, ?)';
              var params = [mb_id, mb_name];
              connection.query(sql,params,function(err,rows,fields) {
                if(err){
                  console.log(err);
                }
              });
          }
      });
 
      // 사용자 입장시 자신의 채팅대화 가져오기
      connection.query('SELECT * FROM chatting WHERE mb_id = ?', mb_id ,function(err,result) {
        io.sockets.in(mb_id).emit('User_Message_Update', {result: result});
      });
    }
  });
 
 
  /* 사용자가 전송한 메시지 받기 */
  socket.on('User_Message_Send'function(data) {
     
    // 데이터베이스에 사용자가 입력한 메시지 작성
    var datetime = new Date();
    var sql      = 'INSERT INTO chatting(mb_id, mb_name, message, is_admin, write_date, write_ip)VALUES(?, ?, ?, ?, ?, ?)';
    var params   = [data.mb_id, data.mb_name, data.message, 'N', datetime, ip_address];
 
    connection.query(sql,params,function(err,rows,fields) {
      if(err){
        console.log(err);
      }else{
 
        // 새로운 글이 작성되면 user-info에 읽지 않음 표시로 업테이트
        var sql    = "UPDATE chatting_room SET is_read = 'N' WHERE mb_id = ?";
        var params = [data.mb_id];
        connection.query(sql, params, function(err, result, fields) {});
 
         connection.query(sql, params, function(err, result, fields) {
          if(err){
            console.log(err);
          } else {
 
            //자신의 글을 가져옴
            connection.query('SELECT * FROM chatting WHERE mb_id = ? order by write_date ASC', data.mb_id ,function(err,result) {
              io.sockets.in(data.mb_id).emit('User_Message_Update', {result: result}); // Room에 입장한 특정 클라이언트에게 메시지 보냄
            });
 
            if(chattingRoom[0!= undefined){
              // 관리자랑 1:1 소통중이라면 해당 사용자를 읽음 표시로 하고, 1:1사용자의 대화내용을 관리자에게 계속 update함
              connection.query("UPDATE chatting_room SET is_read = 'Y' WHERE mb_id = ?", chattingRoom[0], function(err, result) {
                connection.query('SELECT * FROM chatting_room' ,function(err,result) {
                  io.sockets.emit('Manager_User_Info_Reset',
                    {
                      result : result
                    }
                  );
                });
                connection.query('SELECT * FROM chatting WHERE mb_id = ? order by write_date ASC', chattingRoom[0] ,function(err,result) {
                  io.sockets.emit('Manager_User_Message_Update',
                    {
                      result : result
                    }
                  );
                });
              });
            }else{
              // 관리자랑 1:1 소통중은 아니지만 관리자 페이지에서도 새로운 메시지가 왔다는걸 확인 할 수 있도록 초기화 시켜줌
              connection.query('SELECT * FROM chatting_room' ,function(err,result) {
                io.sockets.emit('Manager_User_Info_Reset',
                  {
                    result : result
                  }
                );
              });
            }
          }
        });
      }
    });
  });
});
 
/* 서버를 8080 포트로 listen */
server.listen(8080function() {
  console.log('서버 실행 중..')
});
 
cs

 

 

Step01 - php에서 클라이언트가 채팅버튼을 클릭했을 경우와 클라이언트가 메시지를 보내는 경우

        -> index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
var socket = io()
 
/* 접속 되었을 때 실행 */
socket.on('connect'function() {
  /* 서버에 유저가 접속했다고 알림 */
  socket.emit('NewUser');
});
 
/* User의 메시지를 계속 업테이드 해줌 */
socket.on('User_Message_Update'function(data) {
  var chat      = document.getElementById('chat');
      chat.innerHTML = '';
 
  for (var loop = 0; loop < data.result.length; loop++) {
    var contents = document.createElement('div');
 
    if(data.result[loop].is_admin == 'N'){ 
      // 클라이언트측 메시지
      contents.innerHTML += '<li style="width:100%">' +
                              '<div class="msj macro">' +
                                '<div class="avatar"><img class="img-circle" style="width:100%;" src="https://ptetutorials.com/images/user-profile.png" /></div>' +
                                  '<div class="text text-l">' +
                                  '<p>'+ data.result[loop].message +'</p>' +
                                  '<p><small>'+data.result[loop].write_date+'</small></p>' +
                              '</div>' +
                            '</div>' +
                          '</li>';
    }else{
    // 관리자가 보낸 메시지
      contents.innerHTML += '<li style="width:100%;">' +
                             '<div class="msj-rta macro">' +
                               '<div class="text text-r">' +
                                   '<p>'+data.result[loop].message+'</p>' +
                                   '<p><small>'+data.result[loop].write_date+'</small></p>' +
                               '</div>' +
                            '<div class="avatar" style="padding:0px 0px 0px 10px !important"><img class="img-circle" style="width:100%;" src="https://ptetutorials.com/images/user-profile.png" /></div>' +
                          '</li>';
 
    }
    chat.appendChild(contents);
    chat.scrollTop = chat.scrollHeight; // 스크롤 하단으로 
  }
 
})
 
/* 메시지 전송 함수 */
function message_send() {
  var mb_id   = getUrlParams().mb_id;
  var mb_name = decodeURI(getUrlParams().mb_name);
  var message = document.getElementById('message').value;
 
  if(message == ''){
    alert('답변을 입력해주세요.');
    return false;
  }
 
  document.getElementById('message').value = '';
 
  // 서버로 user_Message_Send 이벤트 전달 + 데이터와 함께
  socket.emit('User_Message_Send', {type: 'message', message: message, mb_id:mb_id, mb_name:mb_name});
}
 
 
// url 파라미터 잘라서 반환하는 함수 
function getUrlParams() {
    var params = {};
    window.location.search.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(str, key, value) { params[key] = value; });
    return params;
}
cs
 
Step02 - 프로세스 이해
1.  클라이언트가 채팅이라는 버튼을 클릭했을때 index.js의 
NewUser라는 함수가 실행이 되어 server.js의 NewUser함수가 실행이 된다.
 
NewUser라는 함수에서는 chatting_room DB에 클라이언트를 저장하고
클라이언트의 대화내용이 있으면 index.js의 User_Message_Update에 보내준다.
 
* index.js의 User_Message_Update는 클라이언트의 대화 메시지를 그려주는 역할을 한다.
 
2. 클라이언트가 메시지를 보내는 경우
- index.js의 message_send() 함수가 실행되어 클라이언트의 메시지와 기타 내용들을
server.js에 있는 User_Message_Send함수로 전달한다.
 
- 전달받은 server.js의 User_Message_Sendg함수는 클라이언트가 입력한 메시지를 DB에 저장하고
저장된 내용을 기반으로 다시 자신의 클라이언트(즉 사용자 본인)에게 내용을 던진다
 
- 여기서 중요한 점은 아래 사진에 있는 네모박스 클라이언트가 메시지를 입력한 경우
관리자 페이지에서도 확일을 할 수 있어야하므로
chattingRoom이라는 배열을 이용하여 관리자에서도 확인 할 수 있도록 한다.
여기에 대한 글은 관리자 부분에서 다시 설명한다.
 
 
 
 

 

728x90
반응형