多個聊天室的專案
Nodejs server side
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var _ = require('lodash');
app.use(express.static('public'));
app.get('/', function (req, res, next) {
res.redirect('/' + randomRoomId(6));
});
app.get('/sockets', function (req, res, next) {
res.send( io.nsps['/'].adapter.rooms);
});
app.get('/allmembers', function (req, res, next) {
res.send( getAllMembers() );
});
app.get('/:roomId', function (req, res, next) {
res.sendFile(__dirname + '/views/rooms.html');
});
http.listen(3000, function () {
console.log("伺服器跑起來啦!");
console.log("在你的瀏覽器網址列輸入 localhost:" + 3000 + " 吧!");
});
var randomRoomId = function (len) {
var text = "";
var possible = "abcdefghijklmnopqrstuvwxyz";
for (var i = 0; i < len; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
};
var getRoomMembers = function (roomId) {
var room = io.nsps['/'].adapter.rooms[roomId];
if (room === undefined) return null;
var roomMates = _.keysIn(room.sockets);
return roomMates;
};
var getAllMembers = function (roomId) {
console.log(io.sockets.connected);
var allMembers = _.keysIn(io.sockets.connected);
return allMembers;
}
io.sockets.on('connection', function (socket) {
socket.on('message', function (roomId,msg) {
console.log("["+socket.id+"] say: "+msg)
io.to(roomId).emit('message', socket.id , msg);
});
socket.on('leave', function (roomId) {
socket.disconnect();
console.log('------------------------------------');
roomMembers = getRoomMembers(roomId);
console.log('Leave room (' + roomId + '), members: ' + JSON.stringify(roomMembers));
io.to(roomId).emit('leave', roomId, socket.id, roomMembers);
});
socket.on('create_or_join', function (roomId) {
console.log('------------------------------------');
var roomMembers = getRoomMembers(roomId);
var roomMemberCount = (roomMembers === null) ? 0 : roomMembers.length;
if (roomMemberCount === 0) {
socket.join(roomId);
roomMembers = getRoomMembers(roomId);
io.to(roomId).emit('create', roomId, socket.id, roomMembers);
console.log('Create room (' + roomId + '), members: ' + JSON.stringify(roomMembers));
} else if (roomMemberCount >= 5) {
console.log('Room (' + roomId + ') is full');
socket.emit('full', roomId);
} else {
socket.join(roomId);
roomMembers = getRoomMembers(roomId);
io.to(roomId).emit('join', roomId, socket.id, roomMembers);
console.log('Join room (' + roomId + '), members: ' + JSON.stringify(roomMembers));
}
});
});
HTML client side
<!doctype html>
<html>
<head>
<title>Socket.IO chat</title>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
<script src="https://unpkg.com/vue"></script>
<link rel="stylesheet" href="css/room.css">
</head>
<body>
<div id="app">
<div v-for="member in members">
<div :id="member" v-bind:class="{ member: true, user: userSocketId==member }">
ID: {{member}}:
<div class="dialog"></div>
</div>
</div>
<input id="m" v-model="msg" v-on:keyup.13="sendMessage" />
<button id="send" @click="sendMessage">傳送</button>
</div>
<script>
$(function () {
var app = new Vue({
el: '#app',
data: {
userSocketId: null,
msg: '',
members: []
},
methods: {
sendMessage: function () {
if (app.msg == "") return;
socket.emit('message', roomId, app.msg);
app.msg = '';
}
}
});
var socket = io.connect();
var roomId = window.location.pathname.slice(1);
socket.on('create', function (roomId, socketId, roomMembers) {
app.userSocketId = socketId;
console.log('Create room (' + roomId + ') - socket ID (' + socketId + ')');
console.log('roomMembers: ' + JSON.stringify(roomMembers));
app.members = roomMembers;
});
socket.on('join', function (roomId, socketId, roomMembers) {
if (app.userSocketId == null) app.userSocketId = socketId;
console.log('Join room (' + roomId + ') - socket ID (' + socketId + ')');
console.log('roomMembers: ' + JSON.stringify(roomMembers));
app.members = roomMembers;
});
socket.on('leave', function (roomId, socketId, roomMembers) {
console.log('Leave room (' + roomId + ') - socket ID (' + socketId + ')');
console.log('roomMembers: ' + JSON.stringify(roomMembers));
app.members = roomMembers;
});
socket.on('full', function (roomId) {
alert('Room "' + roomId + '" is full. We will create a new room for you.');
window.location.href = "/";
});
socket.on('message', function (socketId, message) {
console.log('(' + socketId + ' ) say: ', message);
$("#" + socketId).find(".dialog").html(message);
});
socket.emit('create_or_join', roomId);
window.onunload = confirmExit;
window.onbeforeunload = confirmExit;
function confirmExit() {
socket.emit('leave', roomId);
}
});
</script>
</body>
</html>
CSS
#m {
padding: 10px;
width: 90%;
margin: .5%;
position: fixed;
bottom: 0;
}
#send {
width: 8%;
margin: .5%;
padding: 10px;
position: fixed;
bottom: 0;
right: 5px;
}
.member{
padding:10px;
border-radius: 20px;
font: 20px microsoft jhenghei;
background: LightYellow ;
border: 1px solid yellowgreen;
margin:10px;
display: block;
}
.user{
border: 3px solid green;
}
.dialog{
display: inline;
}