LoginSignup
0
2

More than 3 years have passed since last update.

Node.jsとsocket.ioでLine風チャットを作成してみた4

Last updated at Posted at 2019-07-07

node.jsとsocket.ioを使用する機会があったので、簡単にチャットを作ることにしました。


作成イメージ

2019-07-07_13h24_10.png


ディレクトリ

2019-07-07_13h12_12.png


完成コード

hello.html
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" type="text/css" href="./Line.css">
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="./Line.js"></script>
</head>

<body>
    <div class="line">
    </div>

    <div class="submit">
        <input class="form-control" id="msgForm" autocomplete="off" maxlength="120">
        <input type="button" id="sendButton" onclick="window.message()" value="送信">
    </div>

    <div class="file">
        <input type="file" name="upfile" id="upfile" accept="image/*" capture="camera" />
        <input type="button" onclick="upload()" value="送信">
    </div>
</body>

</html>
hello.CSS
.line {
  overflow:scroll;
  float: left;
  width:750px;
  height:370px;
  padding: 20px 10px;
  max-width: 450px;
  margin: 15px auto;
  font-size: 14px;
  background: #7da4cd;
}

.joincomment{
  text-align:center; 
}

.others{
  display: inline-block;
  position: relative;
  left: -80px;
}

.icon{
    display: inline-block;
    border-radius: 50%;
    width: 40px;
    height: 40px;
    position: relative;
    top:10px;
    left:75px;
}

.name{
  display: inline-block;
  font-size: 12px;
  position: relative;
  top:-35px;
  left:90px;
}

.othercomment {
  display: inline-block;
  position: relative; 
  left:10px;
  margin: 0 0 0 50px;
  padding: 10px;
  max-width: 250px;
  border-radius: 12px;
  background: #edf1ee;
  text-align: left;

}

.othercomment:after {
  content: "";
  display: inline-block;
  position: absolute;
  top: 3px; 
  left: -19px;
  border: 8px solid transparent;
  border-right: 18px solid #edf1ee;
  -webkit-transform: rotate(35deg);
  transform: rotate(35deg);
}
.othercomment p {
  margin: 0;
  padding: 0;
}

.mycomment {
  margin: 10px 0;
  text-align: right;
}
.mycomment p {
  display: inline-block;
  position: relative; 
  margin: 0 10px 0 0;
  padding: 8px;
  max-width: 250px;
  border-radius: 12px;
  background: #30e852;
  font-size: 15px;
}

.mycomment p:after {
  content: "";
  position: absolute;
  top: 3px; 
  right: -19px;
  border: 8px solid transparent;
  border-left: 18px solid #30e852;
  -webkit-transform: rotate(-35deg);
  transform: rotate(-35deg);
}

.submit{
  position: relative;
  top: 450px; 
  left: -460px;
}

#msgForm{
  width:410px;
}


.file{
  position: relative;
  top: 460px; 
  left: -460px;
}
Line.js
var socket = io.connect('http://localhost:3000');
var name = prompt('ニックネームを入力してください', '');
joinUser(name);

socket.on("server_to_client", function (data) {
    appendOtherMsg(data.otherMsg, data.name, data.img);
});

socket.on("server_to_client_join", function (data) {
    appendJoinMsg(data.join);
});

function appendJoinMsg(message) {
    $(".line").append('<div class="joincomment">' + message + '</div><br>');
    $('.line').animate({ scrollTop: $('.line')[0].scrollHeight }, 'fast');
}

function appendOtherMsg(message, name, img) {
    $(".line").append('<div class="others"><img src="' + img + '" class="icon"><span class="name">' + name + '</span><div class="othercomment"><p>' + message + '</p></div></div><br><br>');
    $('.line').animate({ scrollTop: $('.line')[0].scrollHeight }, 'fast');
}

function appendMyMsg(message) {
    $(".line").append('<div class="mycomment"><p>' + message + '</p></div><br>');
    $('.line').animate({ scrollTop: $('.line')[0].scrollHeight }, 'fast');
}

function message() {
    if ($("#msgForm").val() != '') {
        var message = $("#msgForm").val();
        appendMyMsg(message);
        $("#msgForm").val('');
        socket.emit("client_to_server", { message: message, name: name });
    }
}

function joinUser(name) {
    var selectRoom = 1;
    socket.emit("client_to_server_join", { room: selectRoom, name: name });
}

function upload() {
    var img = $("#upfile").val().split("\\");
    socket.emit("client_to_sever_upload", { img: './image/' + img.pop() });
}

$('#msgForm').keypress(function (e) {
    if (e.which == 13 && $("#msgForm").val() != ' ') {
        message();
        return false;
    }
});
chatServer.js
var http = require('http');
var socketio = require('socket.io');
var server = http.createServer(function (req, res) {

}).listen(3000);

var io = socketio.listen(server);

io.sockets.on('connection', function (socket) {
    var room = '';
    var name = '';
    var img = './image/icon.jpg';

    socket.on('client_to_server_join', function (data) {
        room = data.room;
        name = data.name;
        socket.join(room);
        io.to(room).emit('server_to_client_join', { join: name + "さんが入室しました。" });
    });

    socket.on('client_to_sever_upload', function (data) {
        img = data.img;
    });

    socket.on('client_to_server', function (data) {
        socket.broadcast.to(room).emit('server_to_client', { otherMsg: data.message, name: name, img: img });
    });

    socket.on('disconnect', function () {
        if (name == '') {
            console.log("未入室のまま、どこかへ去っていきました。");
        } else {
            io.to(room).emit('server_to_client_join', { join: name + "さんが退室しました。" });
        }
    });
});

感想

データベースなしで作成したため、画像の持ち方は悪いと思います。
CSSに関しては得意ではないので、都度修正してください。画面のサイズでUIが変わると思います。
参考程度にしてください。

0
2
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
0
2