WebSocket-簡易APP應用

完整 Demo:參考github 程式碼

安裝 nodemon

持續監視程式碼,一旦我們做了修改並儲存,nodemon 就會自動重新啟動 Node.js 程式,這樣刷新瀏覽器就能看到變更。

1
npm install -g nodemon


安裝完畢之後,輸入指令,就會啟用「自動偵聽並重啟」的功能:

1
nodemon index.js

nodemon 啟動之後,以可以看到提示字元,如果想要人工手動重啟,也可以輸入rs指令。

前端頁面功能

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
//建立一個WebSocket實體,建立完成自動連線到server
var sock = new WebSocket('ws://localhost:5001');

//定義完成連線時的回呼函式
sock.onopen = function(event) {
setTimeout(function() {
document.getElementById('status').setAttribute('class', 'status_connected');
document.getElementById('status').innerHTML = '<b>Connected</b>';
}, 3000);

//設定按鈕監控click事件
document.querySelector('button').onclick = function() {
var date = new Date();
var data = {
user: document.getElementById('user').value,
msg: document.getElementById('inputBox').value,
time: date.getTime(),
};

//傳送訊之前要先將物件轉為JSON格式
sock.send(JSON.stringify(data));
document.getElementById('inputBox').value = '';
};

//定義收到訊息時的回呼函式
sock.onmessage = function(event) {
console.log(event.data);

//將JSON格式先轉為物件
var newEvent = JSON.parse(event.data);

//判斷資料並分類做處理
switch (newEvent.type) {
case 'request':
var time = new Date(newEvent.time).toLocaleTimeString();
var logArea = document.getElementById('chatArea');
var newArea = document.createElement('div');
newArea.innerHTML =
"<div id='logArea'><div class='card'>" +
'<p>' +
newEvent.user +
':<b>' +
newEvent.msg +
'</b><small>' +
time +
'</small></p></br></div></div>';
logArea.appendChild(newArea);
break;

case 'response':
var time = new Date(newEvent.time).toLocaleTimeString();
var resArea = document.getElementById('chatArea');
var newArea = document.createElement('div');
newArea.innerHTML =
"<div id='resArea'><div class='card'>" +
'<p>' +
newEvent.user +
':<b>' +
newEvent.msg +
'</b><small>' +
time +
'</small></p></br></div></div>';
resArea.appendChild(newArea);
break;

case 'notify':
var time = new Date(newEvent.time).toLocaleTimeString();
var resArea = document.getElementById('chatArea');
var newArea = document.createElement('div');
newArea.innerHTML =
"<div id='resArea'><div class='card'>" +
'<p>' +
newEvent.user +
':<b>' +
newEvent.msg +
'</b><small>' +
time +
'</small></p></br></div></div>';
resArea.appendChild(newArea);
break;
default:
break;
}
};
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div>
<div id='status' class="status_disconnected"><b style="color: white">Disconected</b></div>
<div id='content'>
<span>User:</span>
<select id='user'>
<option>Amy</option>
<option>Bora</option>
<option>Cherry</option>
</select>
</div>
<br/>
<div>
<textarea id='inputBox' type='text' placeholder="Input message here"></textarea>
</div>
<button>Send</button>
<div id='chatArea'>
<!-- 在這裡面處理appendChild() -->

</div>
</div>
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
#chatArea {
border-top: 3px solid white;
/* margin-top:10px; */
background-color: #f1f1f1;
position: relative;
width: 100%;
margin: 0 auto;
}

#logArea {
position: relative;
width: 50%;
left: 0;
border-right: 3px solid white;
}

#resArea {
position: relative;
width: 50%;
left: 50%;
border-left: 3px solid white;
}

.card {
position: relative;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}

後端處理

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
//建立server實體
var webSocketServer = require('ws').Server;
var wss = new webSocketServer({ port: 5001 });

//設計一個計數器,計算當前連線數量
var count = 0;

//定義每當一個連線建立的執行動作
wss.on('connection', function(ws) {
var user = '';
count++;
console.log('Curent clients:' + count);
console.log('[Server] connected!');

//當某個建立連線的ws發送出message,會執行的動作
ws.on('message', function(data) {
//將JSON格式先轉為物件
var newData = JSON.parse(data);
console.log(`[Server] received ${data}`);
user = newData.user;

//將訊息同步傳給「所有」的用戶端瀏覽器,達成訊息同步
wss.clients.forEach((client) => {
//判斷用戶端是否為發出訊息的自己,而做不同的處理
if (client == ws) {
newData.type = 'request';
} else {
newData.type = 'response';
}
client.send(JSON.stringify(newData), (err) => {
if (err) {
console.log(`[Server] error: ${err}`);
}
});
});
});

//當某個用戶端斷線,所執行的動作
ws.on('close', function() {
count--;
console.log('[Server] Lost a client.');
console.log('Online clients:' + count);
var date = new Date();
newData = {
type: 'notify',
user: user,
msg: '[Left chat room]',
time: date.getTime(),
};

//將斷線訊息同步給所有其他用戶
wss.clients.forEach((client) => {
if (client != ws) {
client.send(JSON.stringify(newData), (err) => {
if (err) {
console.log(`[Server] error: ${err}`);
}
});
}
});
});
});
© 2020 Leah's Blog All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero