LoginSignup
4
5

More than 5 years have passed since last update.

【チュートリアル】NodeJS+SocketIOを使おう

Last updated at Posted at 2019-01-28

今回はNodejs+SocketIOの簡単なAppChatを開発しましょう!!
それぞれの技術のホームページ:
- Nodejs
- Socket.io

使用した技術のバージョン

Ejs:2.6.1
Express:4.16.3
Socket.io:2.1.1
Jquery:3.3.1
Nodejs:10.14.1

Socket.io

クライアントはサーバーをアクセスする時、単一のIdが出来ます。
image.png
socket.ioだと、以下のfunctionは非常に大切です
socket.on: Clientはイベントを聞いて、データを貰います
io.sockets.emit: サーバーは全てのClientIdにデータを送ります
Screen Shot 2019-01-28 at 11.32.31 PM.png
socket.emit: イベントをemitしたClientIdだけにデータを送ります
Screen Shot 2019-01-28 at 11.30.11 PM.png
socket.broadcast.emit: イベントをemitしたClientId以外、全てのClientIdにデータを送ります
Screen Shot 2019-01-28 at 11.31.00 PM.png

プロジェクトのディレクトリ

最初はnpm initnpm install express ejs socket.ioをターミナルで書いてください。
その後、以下のようなディレクトリを作成しましょう!

.
├── public
│   ├── jquery-3.3.1.min.js
│   └── layout.css
│   └── main.js
├──  views
│   └── home.ejs
├── server.js
├── package.json

Jqueryのホームページでファイルをダウンロードして、publicにコピーしましょう

コーディング

layout.css
body {
    background-color: #e75400;
}

#wrapper {
    width: 600px;
}

#username {
    background-color: transparent;
    border: solid 1px black;
}

#left, #right {
    min-height: 30%;
}

#left {
    width: 30%;
    float: left;
    background-color: #99d88c;
}

#right {
    width: 70%;
    float: right;
    background-color: #f5f788;
    text-align: right;
}

#box-title {
    border: solid 1px black;
    padding: 5px;
    text-align: center;
    font-weight: bold;
}

#box-content {
    border: solid 1px black;
    padding: 5px;
    border-top: none;
    text-align: center;
}

#list-message {
    height: 200px;
    background-color: #fcb3f0;
    margin-bottom: 15px;
    overflow-y: scroll;
    resize: none;
}

#message {
    width: 85%;
}

#send-message {
    width: 13%;
}
server.js
var express = require('express');


var app = express();

app.use(express.static('./public'));
app.set('view engine', 'ejs');
app.set('views', './views');

var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(process.env.PORT || 3000);

var arrayUser = [];

io.on('connection', function(socket) {
    console.log('Client ' + socket.id + ' connected');

    socket.on('client-send-username', function(data) {
        if(arrayUser.indexOf(data) >= 0) {
            socket.emit('server-send-fail');
        } else {
            arrayUser.push(data);
            socket.username = data;
            socket.emit('server-send-success', data);
            io.sockets.emit('server-send-array-user', arrayUser);
        }
    });

    socket.on('logout', function() {
        arrayUser.splice(arrayUser.indexOf(socket.username), 1);
        socket.broadcast.emit('server-send-array-user', arrayUser);
    });

    socket.on('user-send-message', function(data) {
        io.sockets.emit('server-send-message', {
            username: socket.username,
            message: data
        });
    });

    socket.on('user-typing-message', function() {
        socket.broadcast.emit('server-send-typing', socket.username);
    });

    socket.on('user-stop-typing-message', function() {
        socket.broadcast.emit('server-send-stop-typing', socket.username);
    })
})

app.get('/', function(req, res) {
    res.render('home');
})

※ 全てのsocket.ioの処理コードをio.onの中に入らないと、コードが動きません。

home.ejs
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title> Demo chat app </title>
    <script type="text/javascript" src="jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.1/socket.io.js"></script>
    <script type="text/javascript" src="main.js"></script>
    <link rel="stylesheet" type="text/css" href="layout.css">
</head>
<body>
    <div id="wrapper">
        <div id="login-form">
            <h3> What is your name ? </h3>
            <input type="text" id="username" name="username" >
            <input type="button" value="Register" id="register" >
        </div>
        <div id="chat-form">
            <div id="left">
                <div id="box-title">
                    Online Users
                </div>
                <div id="box-content">

                </div>
            </div>
            <div id="right">
                <div id="welcome">
                    Hello <span id="current-user">  </span>
                    <input type="button" id="logout" name="" value="Logout">
                </div>
                <div id="list-message" scrollable>

                </div>
                <div id="input-message">
                    <input type="text" id="message" name="" placeholder="Input message here">
                    <input type="button" id="send-message" name="" value="Send">
                </div>
            </div>
        </div>   
    </div>
</body>
</html>

※ main.jsでsocket.ioを使えるように、home.ejsの中ではsocket.ioのCDNリンクが必要です。

main.js
var socket = io('http://localhost:3000');

$(document).ready(function() {
    $('#login-form').show();
    $('#chat-form').hide();

    socket.on('server-send-fail', function() {
        alert('The username is already exists !');
    });

    socket.on('server-send-success', function(data) {
        console.log(data);
        $('#current-user').html(data);
        $('#login-form').hide(2000);
        $('#chat-form').show(1000);
    });

    socket.on('server-send-array-user', function(data) {
        $('#box-content').html('');
        data.forEach(function(username) {
            $('#box-content').append('<div class="user-online"> ' + username + '</div>');
        });
    });

    socket.on('server-send-message', function(data) {
        $('#list-message').append('<div>' + data.username + ': ' + data.message + '</div>');
    });

    socket.on('server-send-typing', function(data) {
        $('#list-message').append('<div id="' + data + '">' + data + ' is typing message ... </div>');
    });

    socket.on('server-send-stop-typing', function(data) {
        $('#'+data).remove();
    });

    $('#register').click(function() {
        socket.emit('client-send-username', $('#username').val());
    });

    $('#logout').click(function() {
        socket.emit('logout');
        $('#login-form').show(1000);
        $('#chat-form').hide(2000);
    });

    $('#send-message').click(function() {
        socket.emit('user-send-message', $('#message').val());
    });

    $('#message').focus(function() {
        socket.emit('user-typing-message');
    });

    $('#message').focusout(function() {
        socket.emit('user-stop-typing-message');
    });
})

重大なイベント
1. client-send-username: Registerのボタンをクリックすると、イベントをemitします。
- server-send-success: 登録した名前がない場合です
- server-send-fail: 登録した名前がありました
2. logout: ログアウト、イベントを送ります
3. user-send-message
4. user-typing-message
5. user-stop-typing-message

結果

以下のコマンドラインをターミナルで書きます
node server.js

その後、http://localhost:3000 にアクセスすると、以下の画面が出てきます。
Screen Shot 2019-01-28 at 8.25.28 PM.png
名前を入力して、Registerのボタンをクリックすると、以下のようなチャット画面を移動します。
Screen Shot 2019-01-28 at 8.38.46 PM.png

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5