Node.jsを使ってSocket.ioを用いたチャットルームを作成したいと思います
せっかくなので、前回紹介したYeomanを使って作成
generator-socketioというジェネレータがあるようなのでコレを使います。
まずはジェネレータのインストール
XXXXX:chat XXXXX$ sudo npm install -g generator-socketio
Password:
実行するディレクトリをつくったらyoで実行
今回はbootstrap使用、スタイルシートはCSSを使うことにします
XXXXX:workspace XXXXX$ mkdir chat
XXXXX:workspace XXXXX$ cd chat
XXXXX:chat XXXXX$ yo socketio
_-----_
| |
|--(o)--| .--------------------------.
`---------´ | Welcome to Yeoman, |
( _´U`_ ) | ladies and gentlemen! |
/___A___\ '__________________________'
| ~ |
__'.___.'__
´ ` |° ´ Y `
[?] What do you want to call this project? chat
[?] Write a brief description.
[?] What port number would you like to run on? 1337
chat
to run on port - 1337
[?] Do you want to use Bootstrap? Yes
true
[?] In what format would you like the Bootstrap stylesheets? css
css
create server.js
create views/index.ejs
create public/js/app.js
create Gruntfile.js
create package.json
create bower.json
create .editorconfig
create .jshintrc
create .bowerrc
create .gitignore
~~~
あとはgruntで実行するだけ。あーなんて楽ちん…
XXXXX:chat XXXXX$ grunt
あーbootstrap入れてなかった
Gruntfile.jsを確認した所、public/bowser_componentsにbootstrapファイルを
入れるといいみたいですね
XXXXX:chat XXXXX$ vi Gruntfile.js
~~~
cssmin: {
combine: {
files: {
'public/css/core.css': 'public/bower_components/bootstrap.css/css/bootstrap.css'
~~~
publicにbower_componentsディレクトリを作成し、公式サイトでDLしたbootstrapファイルを入れます
XXXXX:public XXXXX$ mkdir bower_components/
XXXXX:public XXXXX$ mkdir bower_components/bootstrap.css/
もう一回gruntで実行
おおーうまく行った!
すでに基本的なチャット機能が入っているようで、
もう一つブラウザを開いて文章のやりとりをしてみるときちんと動きます
せっかくなので、少し編集を加えてチャット部屋を用意してみることにします
TOP(localhost:1337)にアクセスしたらランダムなユーザ名と部屋IDを作成し、
各部屋(localhost:1337/id)に飛ぶイメージです
以下編集後
server.js 38行目〜
/*************************************
//
// chat app
//
**************************************/
// express magic
var express = require('express');
var app = express();
var server = require('http').createServer(app)
var io = require('socket.io').listen(server);
var device = require('express-device');
var runningPortNumber = process.env.PORT;
app.configure(function(){
// I need to access everything in '/public' directly
app.use(express.static(__dirname + '/public'));
//set the view engine
app.set('view engine', 'ejs');
app.set('views', __dirname +'/views');
app.use(device.capture());
});
// logs every request
app.use(function(req, res, next){
// output every request in the array
console.log({method:req.method, url: req.url, device: req.device});
// goes onto the next function in line
next();
});
app.get("/", function(req, res){
res.redirect('/'+ random_string(12));
});
app.get('/:room', function(req, res) {
res.render('index', {room: req.params.room, name: random_string(5)});
});
io.sockets.on('connection', function (socket) {
var room; // 部屋ID
var name; // ユーザ名
socket.emit('connected');
socket.on('init', function(data) {
room = data.room;
name = data.name;
socket.join(room);
socket.broadcast.to(room).emit('blast', {msg:""+ name +" connected"});
});
socket.on('blast', function(data, fn){
console.log(data);
io.sockets.to(room).emit('blast', {msg:data.msg});
fn();//call the client back to clear out the field
});
socket.on('disconnect', function() {
socket.broadcast.to(room).emit('blast', {msg:""+ name +" disconnected"});
socket.leave(room);
});
});
server.listen(runningPortNumber);
/**
* ランダムな文字列を返す
*/
function random_string(len) {
var base = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
base = base.split('');
var str = '';
var count = base.length;
for(var i=0; i
index.ejsはnameとroomを追加しただけ
views/index.ejs 52行目〜
app.jsも同じくnameとroom追加
public/js/app.js 13行目〜
// shortcut for document.ready
$(function(){
//setup some common vars
var $blastField = $('#blast'),
$allPostsTextArea = $('#allPosts'),
$clearAllPosts = $('#clearAllPosts'),
$sendBlastButton = $('#send'),
$nameField = $('#name'),
$roomField = $('#room');
socket.emit('init', {name:$nameField.val(), room:$roomField.val()});
$sendBlastButton.click(function(e){
var blast = $blastField.val();
var name = $nameField.val();
if(blast.length){
socket.emit("blast", {msg:name +': '+ blast},
function(data){
$blastField.val('');
});
}
});
ここまで編集したらもう一回grunt実行
自動的に部屋へジャンプするようになりました
もう一つウィンドウを開き、同じURLにアクセスした後、
元の画面で確認すると部屋に別の人が入室したことを表示してくれています
もちろんチャットも出来ますし
ついでに退出を知らせる機能もあります
ウィンドウを消すと"●●● disconnected"と表示されることが確認できます
以上。らくちん。