Created
December 29, 2016 01:18
-
-
Save toofusan/acd86ee75cd626e5b4deac488de9989f to your computer and use it in GitHub Desktop.
http://socket.io/get-started/chat/ のHomework実践
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<title>Socket.IO chat</title> | |
<style> | |
* { margin: 0; padding: 0; box-sizing: border-box; } | |
body { font: 13px "Source Sans Pro", Helvetica, Arial, 游ゴシック体, YuGothic, メイリオ, Meiryo, sans-serif; } | |
#top-fixed {padding 5px 0px; position: fixed; top: 0; width: 100%;} | |
#bottom-fixed {padding 5px; position: fixed; bottom: 0; width: 100%;} | |
#container { padding: 15px 5px;} | |
input { border: 0; padding: 10px; width: 80%; margin-right: .5%; } | |
button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; } | |
form#inputArea { background: #000; padding: 3px;} | |
#messages { list-style-type: none; margin: 0; padding: 0; } | |
#messages li { padding: 5px 10px; background: #eeeeee;} | |
#messages li:nth-child(odd) { background: #e2e2e2; } | |
#messages li.sysmessage{background: #fff; padding: 20px 10px; text-align: center; color: #aaaaaa} | |
#modalWindow {position: fixed; top: 0; left: 0; width: 100%; height: 100%; padding: 10px; box-sizing: border-box; background-color: rgba(0,0,0,0.8); z-index: 101} | |
#modalWindow p {color: #fff; margin-bottom: 10px;} | |
#container {z-index: 100;} | |
</style> | |
</head> | |
<body> | |
<div id="container"> | |
<ul id="messages"></ul> | |
<div id="top-fixed"> | |
<p id="members">Now online member is <span></span></p> | |
</div> | |
<div id="bottom-fixed"> | |
<p id="system-text"></p> | |
<form id="inputArea" action="" onsubmit="return false;"> | |
<input id="m" autocomplete="off" placeholder="message"/> | |
<button>Send</button> | |
</form> | |
</div> | |
</div> | |
<div id="modalWindow"> | |
<div> | |
<form id="registNickname" action="" onsubmit="return false;"> | |
<p>Enter your name</p> | |
<input id="nickname" autocomplete="off" placeholder="your name"/> | |
<button>Enter</button> | |
</form> | |
</div> | |
</div> | |
<script src="/socket.io/socket.io.js"></script> | |
<script> | |
'use strict'; | |
const socket = io(); | |
document.addEventListener('DOMContentLoaded', (e) => { | |
const $sendBtn = document.querySelector('button'); | |
const $m = document.querySelector('#m'); | |
const $systemText = document.querySelector('#system-text'); | |
const $messages = document.querySelector('#messages'); | |
const $members = document.querySelector('#members span'); | |
const $modalWindow = document.querySelector('#modalWindow') | |
const $nickname = document.querySelector('#nickname'); | |
const $modalBtn = document.querySelector('#registNickname button'); | |
// ============================== | |
// クライアントから送信 | |
// ============================== | |
// 入室 | |
$modalBtn.addEventListener('click', (e) => { | |
socket.emit('enter room', $nickname.value); | |
$modalWindow.parentNode.removeChild($modalWindow); | |
}); | |
// テキスト入力 | |
let nowTyping = false; | |
$m.addEventListener('keydown', (e) => { | |
socket.emit('start typing'); | |
}); | |
// テキスト送信 | |
$sendBtn.addEventListener("click", (e) => { | |
socket.emit('chat message', $m.value); | |
$m.value = ""; | |
}, false); | |
// ============================== | |
// サーバーからの受信後処理 | |
// ============================== | |
socket.on('newcomer joined', (nickname) => { // 誰かが入室した時 | |
$messages.innerHTML += '<li class="sysmessage">' + nickname + ' joined</li>'; | |
}); | |
socket.on('the number of users', (login_users) => { // 参加者に変動があったとき | |
$members.innerHTML = Object.values(login_users).join(", "); | |
}); | |
socket.on('user disconnect', (exituser) => { // 参加者が退出した時 | |
$messages.innerHTML += '<li class="sysmessage">' + exituser + ' exited</li>'; | |
}); | |
socket.on('start typing', (typinguser) => { // 誰かが文字入力を初めた時 | |
$systemText.innerHTML += typinguser + ' is now typing...'; | |
}); | |
socket.on('stop typing', () => { // 誰かが文字入力を止めた時 | |
$systemText.innerHTML = ''; | |
}); | |
socket.on('chat message', (data) => { // 誰かがテキストを送信した時 | |
$messages.innerHTML += '<li><span>' + data.nickname + ':</span>' + data.msg + '</li>'; | |
$systemText.innerHTML = ''; | |
}); | |
socket.on('reject message', (msg) => { // 自分が直前と同じテキストを送信した時 | |
$systemText.innerHTML = 'same text already posted "' + msg + '"'; | |
}); | |
}); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
// モジュール | |
const app = require('express')(); | |
const http = require('http').Server(app); | |
const io = require('socket.io')(http); | |
let login_users = {}; // 参加者管理 | |
app.get('/', (req, res) => { | |
res.sendfile('index.html'); | |
}); | |
io.on('connection', (socket) => { | |
// 入室処理 | |
socket.on('enter room', (nickname) => { | |
login_users[socket.id] = nickname; | |
socket.broadcast.emit('newcomer joined', login_users[socket.id]); // 入室したことを他の人に通知 | |
io.emit('the number of users', login_users); // 参加者一覧を更新 | |
}); | |
// 退室処理 | |
socket.on('disconnect', () => { | |
socket.broadcast.emit('user disconnect', login_users[socket.id]); // 退室したおとを他の人に通知 | |
delete login_users[socket.id]; | |
io.emit('the number of users', login_users); // 参加者一覧を更新 | |
}); | |
// テキスト入力処理 | |
let nowTyping = 0; | |
socket.on('start typing', () => { | |
if (nowTyping <= 0) { | |
socket.broadcast.emit('start typing', login_users[socket.id]); // 入力開始を他の人に通知 | |
} | |
// 一文字打つごとにカウントアップ。打ってから3秒後にカウントダウンし、カウントが0になると入力停止したとみなす | |
nowTyping++; | |
setTimeout(() => { | |
nowTyping--; | |
if (nowTyping <= 0) { | |
socket.broadcast.emit('stop typing'); // 入力停止を他の人に通知 | |
} | |
}, 3000); | |
}); | |
// テキスト投稿処理 | |
let latestmsg = ""; | |
socket.on('chat message', (msg) => { | |
// 直前の投稿と同じ時はエラー文を出す | |
if (msg === latestmsg) { | |
io.to(socket.id).emit('reject message', msg); | |
return; | |
} | |
latestmsg = msg; | |
io.emit('chat message', { // テキスト投稿 | |
nickname: login_users[socket.id], | |
msg: msg | |
}); | |
}); | |
}); | |
http.listen(3000, () => { | |
console.log('listening on *:3000'); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment