60
65

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vue.js+Node.jsを利用したチャットアプリの作成

Last updated at Posted at 2020-09-05

はじめに

最近Node.jsの勉強をしたので、何かしらのアウトプットを行おうとチャットアプリを作成しました。その備忘録です。
機能としては、簡単なログイン・ログアウト機能、チャット機能を実装しました。

成果物

sample_other.gif

利用したライブラリ

  • Vue.js
    • VueCLI…Vue.js向けのアプリケーション開発環境セットアップなどの機能を提供するCLIツール
    • vuetify…Vueのアプリケーションのデザインを容易に整えてくれるライブラリ
    • vuex…vue全体で利用できるデータストアを管理できるライブラリ
    • vuex-persistedstate…vuexの値をローカルストレージに保存するプラグイン
    • socket.io-client…socket.ioでサーバへ接続するためのクライアント用ライブラリ
  • Node.js
    • express…Node.jsで使用するWebアプリのフレームワーク
    • socket.io…Webのリアルタイム通信を可能にするライブラリ
    • mysql…MySQLをNode.jsから扱えるライブラリ

ディレクトリ構成

chatapp/
├ frontend/ ( VueCLIで作成されたプロジェクト )
|  ├ src/
|  | ├ components/
|  |   ├ Chat.vue
|  |   └ MenuBar.vue  
|  ├ store
|  | ├ index.js
|  ├ views
|  | ├ Home.vue
|  | ├ Login.vue
|  ├ App.vue
|  └ …etc
└ backend/ (自分で作成)
   ├ bin/
   | └ www
   ├ public
   | └ javascripts
   |    └ db_config.js
   ├ routes
   | ├ delete.js
   | ├ getHistories.js
   | └ login.js
   ├ app.js
   └ …etc

環境イメージ図

全部localhostで完結せず、勉強のためにDBだけ別にしてみました。
image.png

初期準備

Node.jsのインストール

公式サイトからダウンロードします。

$ node -v
v12.18.3

$ npm -v
6.14.6

フロントエンド(Vue.js)の初期準備

公式サイトに従ってインストールしていきます。

$npm install -g @vue/cli

$vue --version
@vue/cli 4.5.4

次にプロジェクトを作成します。

$vue create frontend

コンソールに選択肢が出てくるのですが、Manually select featuresを選択し、Vuexを追加で選択します。

Vue CLI v4.5.4
? Please pick a preset: Manually select features
? Check the features needed for your project: 
 (*) Choose Vue version
 (*) Babel
 ( ) TypeScript
 ( ) Progressive Web App (PWA) Support        
 ( ) Router
>(*) Vuex
 ( ) CSS Pre-processors
 (*) Linter / Formatter
 ( ) Unit Testing
 ( ) E2E Testing

次にVue.jsのバージョンを選択します。今回は2.xを選択します。

? Choose a version of Vue.js that you want to start the project with (Use arrow keys)     
> 2.x
  3.x (Preview)

次にESlintの設定を選択します。今回はエラー防止のみのESLint with error prevention onlyを選択します。

? Pick a linter / formatter config: 
> ESLint with error prevention only 
  ESLint + Airbnb config
  ESLint + Standard config
  ESLint + Prettier

次にLintをかけるタイミングをどうするか選択します。今回はセーブした場合にかけます。

? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)
>(*) Lint on save
 ( ) Lint and fix on commit

次に各種設定をどこに置くか選択します。設定ファイルは個別に管理するのでIn dedicated config filesを選択します。

? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
> In dedicated config files
  In package.json

最後にこの設定をプリセットとして保存するか選択できます。今回はNを選択します。

? Save this as a preset for future projects? (y/N) N

プロジェクトを作成できたので、コマンドを入力し、http://localhost:8080にアクセスします。

$ cd frontend/
$ npm run serve

無事起動できたことが確認できました。
image.png
次にVuetifyを利用するためにVuetifyをインストールしましょう。
Vuetifyでもプリセットを聞かれるのでDefaultを選択します。

$ vue add vuetify

Vuetifyが適用されたのが確認できました。
image.png

バックエンド(Node.js)の初期準備

今回はExpressを利用してバックエンドのアプリケーションを作成するのですが、一から作るのには時間がかかるので、Express Generatorを利用して基本的な部分は作ってもらいます。
※ただExpress Generatorを利用すると今回は利用しないejsファイル( javascript用のテンプレートエンジン)までも作成されたり、不要なルーティングの設定も追加されてしまいます。

$ npm install -g express-generator
$ express -e backend

まだ必要なパッケージが用意されていないので、インストールしましょう。

$ cd backend
$ npm install

実際に起動できるか確認します。コマンドを入力し、http://localhost:3000にアクセスします。

$ npm start

無事起動できたことが確認できました。
image.png

DBの初期準備

今回はVM(CentOS Linux release 8.1.1911)を立ててそこにMySQLをインストールしてきます。
まずはインストールして利用しているMySQLをアンインストールしていきます。
参考記事:CentOSにインストールしたMySQLを削除する

MySQLのアンインストール

①稼働しているMySQLを停止します。

$ mysqld --version
/usr/libexec/mysqld  Ver 8.0.17 for Linux on x86_64 (Source distribution)

$ su

# systemctl stop mysqld.service
# systemctl status mysqld.service
   mysqld.service - MySQL 8.0 database server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since Sun 2020-08-23 17:36:29 JST; 42s ago

②インストール済みのMySQLの確認をします。

# rpm -qa | grep -i mysql
mysql-8.0.17-3.module_el8.0.0+181+899d6349.x86_64
mysql80-community-release-el8-1.noarch
mysql-common-8.0.17-3.module_el8.0.0+181+899d6349.x86_64
mysql-server-8.0.17-3.module_el8.0.0+181+899d6349.x86_64
mysql-errmsg-8.0.17-3.module_el8.0.0+181+899d6349.x86_64

③MySQL8をアンインストールします。

# yum remove mysql*
モジュラーの依存に関する問題:

 問題 1: conflicting requests
  - nothing provides module(perl:5.26) needed by module perl-DBD-SQLite:1.58:8010020191114033549:073fa5fe-0.x86_64
 問題 2: conflicting requests
  - nothing provides module(perl:5.26) needed by module perl-DBI:1.641:8010020191113222731:16b3ab4d-0.x86_64
依存関係が解決しました。
=============================================================================================================================================================================================
 パッケージ                                         アーキテクチャー               バージョン                                                    リポジトリー                          サイズ
=============================================================================================================================================================================================
削除中:
 mysql                                              x86_64                         8.0.17-3.module_el8.0.0+181+899d6349                          @AppStream                             67 M
 mysql-common                                       x86_64                         8.0.17-3.module_el8.0.0+181+899d6349                          @AppStream                            518 k
 mysql-errmsg                                       x86_64                         8.0.17-3.module_el8.0.0+181+899d6349                          @AppStream                            7.8 M
 mysql-server                                       x86_64                         8.0.17-3.module_el8.0.0+181+899d6349                          @AppStream                            138 M
 mysql80-community-release                          noarch                         el8-1                                                         @@commandline                          29 k
未使用の依存関係の削除:
 mariadb-connector-c-config                         noarch                         3.0.7-1.el8                                                   @AppStream                            497
 mecab                                              x86_64                         0.996-1.module_el8.0.0+41+ca30bab6.9                          @AppStream                            2.2 M
 protobuf-lite                                      x86_64                         3.5.0-7.el8                                                   @AppStream                            508 k

トランザクションの概要
=============================================================================================================================================================================================
削除  8 パッケージ

解放された容量: 216 M
これでよろしいですか? [y/N]: y
トランザクションの確認を実行中
トランザクションの確認に成功しました。
トランザクションのテストを実行中
トランザクションのテストに成功しました。
トランザクションを実行中
  準備             :                                                                                                                                                                     1/1
  scriptletの実行中: mysql-server-8.0.17-3.module_el8.0.0+181+899d6349.x86_64                                                                                                            1/1
  scriptletの実行中: mysql-server-8.0.17-3.module_el8.0.0+181+899d6349.x86_64                                                                                                            1/8
  削除             : mysql-server-8.0.17-3.module_el8.0.0+181+899d6349.x86_64                                                                                                            1/8
  scriptletの実行中: mysql-server-8.0.17-3.module_el8.0.0+181+899d6349.x86_64                                                                                                            1/8
  削除             : mysql-errmsg-8.0.17-3.module_el8.0.0+181+899d6349.x86_64                                                                                                            2/8
  削除             : mysql80-community-release-el8-1.noarch                                                                                                                              3/8
  削除             : mysql-8.0.17-3.module_el8.0.0+181+899d6349.x86_64                                                                                                                   4/8
  削除             : mysql-common-8.0.17-3.module_el8.0.0+181+899d6349.x86_64                                                                                                            5/8
  削除             : mariadb-connector-c-config-3.0.7-1.el8.noarch                                                                                                                       6/8
  削除             : mecab-0.996-1.module_el8.0.0+41+ca30bab6.9.x86_64                                                                                                                   7/8
  scriptletの実行中: mecab-0.996-1.module_el8.0.0+41+ca30bab6.9.x86_64                                                                                                                   7/8
  削除             : protobuf-lite-3.5.0-7.el8.x86_64                                                                                                                                    8/8
  scriptletの実行中: protobuf-lite-3.5.0-7.el8.x86_64                                                                                                                                    8/8
  検証             : mariadb-connector-c-config-3.0.7-1.el8.noarch                                                                                                                       1/8
  検証             : mecab-0.996-1.module_el8.0.0+41+ca30bab6.9.x86_64                                                                                                                   2/8
  検証             : mysql-8.0.17-3.module_el8.0.0+181+899d6349.x86_64                                                                                                                   3/8
  検証             : mysql-common-8.0.17-3.module_el8.0.0+181+899d6349.x86_64                                                                                                            4/8
  検証             : mysql-errmsg-8.0.17-3.module_el8.0.0+181+899d6349.x86_64                                                                                                            5/8
  検証             : mysql-server-8.0.17-3.module_el8.0.0+181+899d6349.x86_64                                                                                                            6/8
  検証             : mysql80-community-release-el8-1.noarch                                                                                                                              7/8
  検証             : protobuf-lite-3.5.0-7.el8.x86_64                                                                                                                                    8/8

削除しました:
  mysql-8.0.17-3.module_el8.0.0+181+899d6349.x86_64             mysql-common-8.0.17-3.module_el8.0.0+181+899d6349.x86_64      mysql-errmsg-8.0.17-3.module_el8.0.0+181+899d6349.x86_64
  mysql-server-8.0.17-3.module_el8.0.0+181+899d6349.x86_64      mysql80-community-release-el8-1.noarch                        mariadb-connector-c-config-3.0.7-1.el8.noarch
  mecab-0.996-1.module_el8.0.0+41+ca30bab6.9.x86_64             protobuf-lite-3.5.0-7.el8.x86_64

完了しました!

④データベースを削除します。

rm -rf /var/lib/mysql
次にMySQL8をインストールしていきます。

参考記事:
CentOS7にMySQL8をインストールして初期パスワードを変更する
MySQL 8.0 を CentOS 8.1 にインストールする手順

① dnfコマンド利用してrpmパッケージをインストールします。

# dnf localinstall https://dev.mysql.com/get/mysql80-community-release-el8-1.noarch.rpm
mysql80-community-release-el8-1.noarch.rpm                                                                                                                    21 kB/s |  30 kB     00:01
依存関係が解決しました。
=============================================================================================================================================================================================
 パッケージ                                                アーキテクチャー                       バージョン                              リポジトリー                                 サイズ
=============================================================================================================================================================================================
インストール:
 mysql80-community-release                                 noarch                                 el8-1                                   @commandline                                  30 k

トランザクションの概要
=============================================================================================================================================================================================
インストール  1 パッケージ

合計サイズ: 30 k
インストール済みのサイズ: 29 k
これでよろしいですか? [y/N]: y
パッケージのダウンロード:
トランザクションの確認を実行中
トランザクションの確認に成功しました。
トランザクションのテストを実行中
トランザクションのテストに成功しました。
トランザクションを実行中
  準備             :                                                                                                                                                                     1/1
  インストール中   : mysql80-community-release-el8-1.noarch                                                                                                                              1/1
  検証             : mysql80-community-release-el8-1.noarch                                                                                                                              1/1

インストール済み:
  mysql80-community-release-el8-1.noarch

完了しました!

②MySQLのリポジトリが有効になっていることを確認します。

dnf repolist enabled | grep "mysql.*-community.*"
mysql-connectors-community           MySQL Connectors Community               74
mysql-tools-community                MySQL Tools Community                    33
mysql80-community                    MySQL 8.0 Community Server               51

デフォルトデフォルトのMySQLモジュールを無効化します。
# dnf module disable mysql
依存関係が解決しました。
=============================================================================================================================================================================================
 パッケージ                                   アーキテクチャー                            バージョン                                      リポジトリー                                 サイズ
=============================================================================================================================================================================================
モジュールプロファイルの無効化:
 mysql/server
モジュールの無効化:
 mysql

トランザクションの概要
=============================================================================================================================================================================================

これでよろしいですか? [y/N]: y
完了しました!

③リポジトリからインストールするパッケージを確認します。

dnf info mysql-community-server
利用可能なパッケージ
名前         : mysql-community-server
バージョン   : 8.0.21
リリース     : 1.el8
Arch         : x86_64
サイズ       : 53 M
ソース       : mysql-community-8.0.21-1.el8.src.rpm
リポジトリー : mysql80-community
概要         : A very fast and reliable SQL database server
URL          : http://www.mysql.com/
ライセンス   : Copyright (c) 2000, 2020, Oracle and/or its affiliates. Under GPLv2 license as shown in the Description field.
説明         : The MySQL(TM) software delivers a very fast, multi-threaded, multi-user,
             : and robust SQL (Structured Query Language) database server. MySQL Server
             : is intended for mission-critical, heavy-load production systems as well
             : as for embedding into mass-deployed software. MySQL is a trademark of
             : Oracle and/or its affiliates
             :
             : The MySQL software has Dual Licensing, which means you can use the MySQL
             : software free of charge under the GNU General Public License
             : (http://www.gnu.org/licenses/). You can also purchase commercial MySQL
             : licenses from Oracle and/or its affiliates if you do not wish to be bound by the terms of
             : the GPL. See the chapter "Licensing and Support" in the manual for
             : further info.
             :
             : The MySQL web site (http://www.mysql.com/) provides the latest news and
             : information about the MySQL software.  Also please see the documentation
             : and the manual for more information.
             :
             : This package includes the MySQL server binary as well as related utilities
             : to run and administer a MySQL server.

④確認できたので、インストールします。

# dnf install mysql-community-server

依存関係が解決しました。
=============================================================================================================================================================================================
 パッケージ                                           アーキテクチャー                     バージョン                                  リポジトリー                                    サイズ
=============================================================================================================================================================================================
インストール:
 mysql-community-server                               x86_64                               8.0.21-1.el8                                mysql80-community                                53 M
依存関係のインストール:
 mysql-community-client                               x86_64                               8.0.21-1.el8                                mysql80-community                                12 M
 mysql-community-common                               x86_64                               8.0.21-1.el8                                mysql80-community                               621 k
 mysql-community-libs                                 x86_64                               8.0.21-1.el8                                mysql80-community                               1.4 M

トランザクションの概要
=============================================================================================================================================================================================
インストール  4 パッケージ

ダウンロードサイズの合計: 67 M
インストール済みのサイズ: 317 M
これでよろしいですか? [y/N]: y
パッケージのダウンロード:
(1/4): mysql-community-common-8.0.21-1.el8.x86_64.rpm                                                                                                        906 kB/s | 621 kB     00:00
(2/4): mysql-community-libs-8.0.21-1.el8.x86_64.rpm                                                                                                          2.1 MB/s | 1.4 MB     00:00
(3/4): mysql-community-client-8.0.21-1.el8.x86_64.rpm                                                                                                        4.6 MB/s |  12 MB     00:02
(4/4): mysql-community-server-8.0.21-1.el8.x86_64.rpm                                                                                                        4.3 MB/s |  53 MB     00:12
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
合計                                                                                                                                                         5.2 MB/s |  67 MB     00:12
警告: /var/cache/dnf/mysql80-community-b1f1ed5ba88ce0f8/packages/mysql-community-client-8.0.21-1.el8.x86_64.rpm: ヘッダー V3 DSA/SHA1 Signature、鍵 ID 5072e1f5: NOKEY
MySQL 8.0 Community Server                                                                                                                                    27 MB/s |  27 kB     00:00
GPG 鍵 0x5072E1F5 をインポート中:
 Userid     : "MySQL Release Engineering <mysql-build@oss.oracle.com>"
 Fingerprint: A4A9 4068 76FC BD3C 4567 70C8 8C71 8D3B 5072 E1F5
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
これでよろしいですか? [y/N]: y
鍵のインポートに成功しました
トランザクションの確認を実行中
トランザクションの確認に成功しました。
トランザクションのテストを実行中
トランザクションのテストに成功しました。
トランザクションを実行中
  準備             :                                                                                                                                                                     1/1
  インストール中   : mysql-community-common-8.0.21-1.el8.x86_64                                                                                                                          1/4
  インストール中   : mysql-community-libs-8.0.21-1.el8.x86_64                                                                                                                            2/4
  scriptletの実行中: mysql-community-libs-8.0.21-1.el8.x86_64                                                                                                                            2/4
  インストール中   : mysql-community-client-8.0.21-1.el8.x86_64                                                                                                                          3/4
  scriptletの実行中: mysql-community-server-8.0.21-1.el8.x86_64                                                                                                                          4/4
  インストール中   : mysql-community-server-8.0.21-1.el8.x86_64                                                                                                                          4/4
  scriptletの実行中: mysql-community-server-8.0.21-1.el8.x86_64                                                                                                                          4/4
  検証             : mysql-community-client-8.0.21-1.el8.x86_64                                                                                                                          1/4
  検証             : mysql-community-common-8.0.21-1.el8.x86_64                                                                                                                          2/4
  検証             : mysql-community-libs-8.0.21-1.el8.x86_64                                                                                                                            3/4
  検証             : mysql-community-server-8.0.21-1.el8.x86_64                                                                                                                          4/4

インストール済み:
  mysql-community-server-8.0.21-1.el8.x86_64     mysql-community-client-8.0.21-1.el8.x86_64     mysql-community-common-8.0.21-1.el8.x86_64     mysql-community-libs-8.0.21-1.el8.x86_64

完了しました!

⑤MySQLがインストールされていることを確認します。

# mysqld --version
/usr/sbin/mysqld  Ver 8.0.21 for Linux on x86_64 (MySQL Community Server - GPL)
次にMySQLの初期設定をしてきます

①パスワードのポリシーの設定を変更します。デフォルトではパスワードポリシーの制約が強く、なかなかパスワードを登録できませんでした。

# vi /etc/my.cnf
[変更:コメントアウトを外す]
default_authentication_plugin=mysql_native_password

[追加]
# パスワードポリシー
validate_password.length=4
validate_password.mixed_case_count=0
validate_password.number_count=0
validate_password.special_char_count=0
validate_password.policy=LOW

②MySQLを起動し、自動起動の設定を追加します。

# systemctl start mysqld.service
# systemctl enable mysqld.service

③mysqld.logから初期パスワードを検索します。


# grep 'temporary password' /var/log/mysqld.log
2020-08-23T08:55:06.087398Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: 43+;S.lyoamX

④パスワードの更新と初期設定


# mysql_secure_installation
# mysql -u root -p
Enter password:[更新したパスワードの入力]
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 8.0.21

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

⑤localhost以外からも接続できるdevユーザを作成します。
MySQLはデフォルトでlocalhostからしか接続できない設定なので、localhost以外から接続できるユーザを作成しないと疎通できません。

mysql> create user 'dev'@'%' identified by '[パスワード]';
mysql> grant all on *.* to 'dev'@'%';

⑥データベースの作成

mysql> create database chat_app_db;
mysql> use chat_app_db
Database changed

mysql> INSERT INTO user_informations (user_id, password)
VALUES ('test', '1234');

あとはNode.jsからSQL文を実行してDB操作をするため、Node.jsのポート3000番を開けます。これをしないとファイヤーウォールでNode.jsからのアクセスが弾かれてDB操作ができません。

# firewall-cmd --zone=public --add-port=3000/tcp --permanent

ログイン・ログアウト機能

ログイン機能ではフロント(Vue.js)からaxiosを利用してバックエンド(Node.js)にHTTPリクエストを送ります。
なのでまずaxiosをインストールします。

$ npm install --save axios

ただこのままだとフロントとバックが異なるオリジンとして捉えられてしまい、CORSを有効化していないため、HTTP通信ができません。フロントはnpm run serveでオリジンがhttp://localhost:8080、バックはnpm startでオリジンがhttp://localhost:3000となり、ポート番号が異なるため、異なるオリジンとして捉えられます。

CORSの有効化を行うためには、Node.jsのapp.jsに以下を追加しましょう。
app.use()がまとまっている部分がありますが、その一番最初に記載しましょう。順番を間違えるとCORSの有効化ができません。

app.js
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  next();
 });

また、バックエンド側ではMySQLへのアクセスを行うために、MYSQLモジュールをインポートします。

$ npm install --save mysql

実際にログインの処理を記載してみたらうまくいきました。
○Vue.js

App.vue
<template>
  <v-app>
    <login v-if="!isLogin"></login>
    <home v-else />
  </v-app>
</template>

<script>
import Login from "@/views/Login.vue";
import Home from "@/views/Home.vue";
import { mapState } from "vuex";

export default {
  name: "App",
  components: {
    Login,
    Home,
  },
  computed: {
    ...mapState(["isLogin"]),
  },
};
</script>


Login.vue
<template>
  <div class="login">
    <v-container class="fill-height" fluid>
      <v-row
        align="center"
        justify="center"
        class="headline font-italic font-weight-medium text--secondary"
      >
        <v-col cols="12" sm="8" md="6" lg="4">
          <v-icon large>mdi-chat-processing-outline</v-icon>ChatApp
        </v-col>
      </v-row>
      <v-row align="center" justify="center">
        <v-col cols="12" sm="8" md="6" lg="4">
          <v-card class="elevation-12">
            <v-toolbar color="primary" dark flat>
              <v-toolbar-title>Login form</v-toolbar-title>
              <v-spacer></v-spacer>
            </v-toolbar>
            <v-card-text>
              <v-form>
                <v-text-field
                  label="UserId"
                  name="login"
                  prepend-icon="mdi-account"
                  type="text"
                  v-model="userId"
                ></v-text-field>

                <v-text-field
                  id="password"
                  label="Password"
                  name="password"
                  prepend-icon="mdi-lock"
                  :append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
                  :type="showPassword ? 'text' : 'password'"
                  @click:append="showPassword = !showPassword"
                  @keyup.enter="login"
                  v-model="password"
                ></v-text-field>
              </v-form>
            </v-card-text>
            <v-card-actions>
              <v-row align="center" justify="space-around">
                <v-btn color="#B2EBF2" @click="login">Login</v-btn>
              </v-row>
            </v-card-actions>
          </v-card>
        </v-col>
      </v-row>
    </v-container>
  </div>
</template>

<script>
export default {
  name: "Login",
  components: {},
  data: () => ({
    showPassword: false,
    userId: "",
    password: "",
  }),
  methods: {
    login() {
      // 入力されたログイン情報が正しいか確認
      this.$store.dispatch("login", {
        userId: this.userId,
        password: this.password,
      });
    },
  },
};
</script>
store>index.js
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
import createPersistedState from 'vuex-persistedstate';

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    isLogin: false,
    userId: '',
    password: ''
  },
  mutations: {
    login(state, param) {
      state.isLogin = true;
      state.userId = param.userId;
      state.password = param.password;
    },
    logout(state) {
      state.isLogin = false;
      state.userId = '';
      state.password = '';
    }
  },
  actions: {
    async login({ commit }, { userId, password }) {
      const param = {
        userId: userId,
        password: password
      }

      try {
        const loginResult = await axios.post('http://localhost:3000/login', param);
        if (loginResult.data === 'OK') {
          // 認証に成功した場合
          commit('login', param);
        } else {
          // 認証に失敗した場合
          console.log('認証に失敗しました。');
        }
      } catch{
        alert('処理に失敗しました。')
      }

    },
    logout({ commit }) {
      commit('logout');
    }
  },
  plugins:[createPersistedState()]
})

○Node.js

login.js
var express = require('express');
var router = express.Router();

var mysql = require('mysql');
const config  = require('../public/javascripts/db_config.js');

/* GET home page. */
router.post('/', function (req, res, next) {

    // フロントからのパラメータ取得
    const userId = req.body.userId;
    const password = req.body.password;

    // コネクションの用意
    const connection = mysql.createConnection(config.mysql_setting);

    connection.query(config.loginSQL, [userId, password],
        function (error, results, fields) {
            console.log(results);
            if (results.length >= 1) {
                res.send('OK');
            } else {
                res.send('NG');
            }
        }
    );
});

module.exports = router;

最初は下記mysql_settingtimezoneを入れずに確認をしていたのですが、datetime型の値をNode.jsで操作した場合、JSTではなくUTC表記で出力されたため、timezone:jstを入れています。
参考記事:mysqlモジュールでDB操作

db_config.js
exports.mysql_setting = {
    host: '*',
    user: 'dev',
    password: '*',
    database: 'chat_app_db',
    timezone: 'jst'
};
exports.loginSQL = 'SELECT * from user_informations where user_id=? AND password=?'
exports.insertRecordSQL = 'INSERT INTO chat_histories(history_index,user_id,message,date_time) VALUES(?, ?, ?, ?)';
exports.getHistoriesSQL = 'SELECT * FROM chat_histories';
exports.deleteHistorySQL = 'TRUNCATE TABLE chat_histories';

チャット機能

○Vue.js

MenuBar.vue
<template>
  <v-app-bar app color="primary" dark>
    <v-spacer></v-spacer>
    <v-btn @click="logout">
      <span class="mr-2">Logout</span>
      <v-icon>mdi-home-export-outline</v-icon>
    </v-btn>
  </v-app-bar>
</template>

<script>
export default {
  name: "MenuBar",
  components: {},
  methods: {
    logout() {
      // ログアウト処理実施
      this.$store.dispatch("logout");
    },
  },
};
</script>
Chat.vue
<template>
  <v-container>
    <v-row class="text-center">
      <v-col cols="12" style="height:80vh">
        <v-toolbar color="#BBDEFB" light>
          <v-toolbar-title>Welcome ChatApp</v-toolbar-title>
          <v-spacer></v-spacer>
          <v-btn @click="deleteRecord">Delete Old Chat</v-btn>
        </v-toolbar>
        <!-- v-card内チャットをスクロールさせるためにclass="overflow-y-auto"を指定 -->
        <v-card height="90%" width="100%" class="overflow-y-auto">
          <!-- チャットの表示 -->
          <v-list two-line subheader>
            <v-list-item v-for="(message,index) in messages" :key="index">
              <v-list-item-avatar>
                <v-icon>mdi-account-circle</v-icon>
              </v-list-item-avatar>
              <v-list-item-content>
                <v-list-item-title v-text="message.user_id"></v-list-item-title>
                <v-list-item-subtitle v-text="message.message"></v-list-item-subtitle>
                <v-list-item-subtitle v-text="message.date_time"></v-list-item-subtitle>
              </v-list-item-content>
            </v-list-item>
            <v-divider inset v-if="messages.length > 0"></v-divider>
          </v-list>
        </v-card>
        <v-card height="10%" width="100%" color="#B2DFDB" class="pa-sm-3 pa-lg-3 pa-md-4">
          <v-text-field
            v-model="message"
            solo
            clearable
            append-outer-icon="mdi-send"
            @click:append-outer="sendMessage"
            @keyup.enter="sendMessage"
          ></v-text-field>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
import io from "socket.io-client";
import axios from "axios";

export default {
  name: "Chat",
  data: () => ({
    message: "",
    messages: [],
    userId: "",
    socket: "",
  }),
  methods: {
    //チャットを投稿する処理
    sendMessage() {
      this.userId = this.$store.state.userId;
      const date = new Date();
      const date_time = `${date.getFullYear().toString()}-${(
        "00" + (date.getMonth() + 1).toString()
      ).slice(-2)}-${("00" + date.getDate().toString()).slice(-2)} ${(
        "00" + date.getHours().toString()
      ).slice(-2)}:${("00" + date.getMinutes().toString()).slice(-2)}:${(
        "00" + date.getSeconds().toString()
      ).slice(-2)}`;

      // Socketを利用してサーバと通信を行う。
      this.socket.emit("SEND_MESSAGE", {
        user_id: this.userId,
        message: this.message,
        date_time: date_time,
      });
      this.message = "";
    },
    // 投稿したチャットの削除
    async deleteRecord() {
      try {
        const result = await axios.post("http://localhost:3000/delete");
        if (result.data === "OK") {
          // 削除に成功した場合履歴の初期化
          this.messages = [];
        } else {
          // 削除に失敗した場合
          console.log("削除に失敗しました。");
        }
      } catch {
        alert("処理に失敗しました。");
      }
    },
  },

  async mounted() {
    this.socket = io("localhost:3000");

    // 初期表示時にDBのレコードを取得する
    try {
      const result = await axios.post("http://localhost:3000/getHistories");
      if (result.data !== "NG") {
        // 履歴の取得に成功した場合
        this.messages = result.data;
      } else {
        // 履歴の取得に失敗した場合
        console.log("履歴の表示に失敗しました。");
      }
    } catch {
      alert("処理に失敗しました。");
    }

    // 投稿されたデータの取得
    this.socket.on("MESSAGE", (data) => {
      this.messages = data;
    });
  },
};
</script>

<style scoped>
.v-list-item__content {
  text-align: left;
}
</style>

○Node.js

wwwファイルに以下の記述を追加することで、Socket.ioの機能を利用することができます。

/**
 * ADDED!! Socket.IO Connection.
 */
var mysql = require('mysql');
const config  = require('../public/javascripts/db_config.js');

io.on('connection', function (socket) {
  // フロント側からチャットが投下された時に発火するイベント
  socket.on('SEND_MESSAGE', function (data) {

    // コネクションの用意
    const connection = mysql.createConnection(config.mysql_setting);

    // レコード件数の取得
    connection.query(config.getHistoriesSQL, function (error, results, fields) {
      const countUpNum = results.length + 1;
      data.index = countUpNum
      results.push(data);
      // 後続の作業を待つ必要がないため、フロントに値を返す。
      io.emit('MESSAGE', results)

      // レコード挿入
      connection.query(config.insertRecordSQL, [countUpNum, data.user_id, data.message, data.date_time],
        function (error, results, fields) {
          // ログ出力
          if (!error) {
            console.log(`INSERT成功:${results}`);
          } else {
            console.log(`INSERT失敗:${error}`);
          }
        }
      );
    })
  });
});

delete.js
var express = require('express');
var router = express.Router();

var mysql = require('mysql'); //★追加
const config  = require('../public/javascripts/db_config.js');

// 削除フォームの送信処理
router.post('/', (req, res, next) => {

  // データベースの設定情報
  var connection = mysql.createConnection(config.mysql_setting);

  // データを取り出す
  connection.query(config.deleteHistorySQL, function (error, results, fields) {
    if (!error) {
      res.send('OK');
    } else {
      res.send('NG');
    }
  }
  );
});

module.exports = router;
getHistories.js
var express = require('express');
var router = express.Router();

var mysql = require('mysql');
const config  = require('../public/javascripts/db_config.js');

// 画面が表示された際に実行される処理
router.post('/', (req, res, next) => {

  // データベースの設定情報
  var connection = mysql.createConnection(config.mysql_setting);

  // データを取り出す
  connection.query(config.getHistoriesSQL, function (error, results, fields) {
    if (!error) {
      res.send(results);
    } else {
      res.send('NG');
    }
  }
  );
});

module.exports = router;

Vuejsのコードはこちらに、Node.jsのコードはこちらにアップしております。
よろしればアドバイス頂けますと幸いです。

最後に

次はこのチャットアプリの機能を充実させるか別のアプリをVue.jsとNode.jsを利用して作ってみたいと思っています。

参照

Vue.js公式サイト
CentOSにインストールしたMySQLを削除する
CentOS7にMySQL8をインストールして初期パスワードを変更する
MySQL 8.0 を CentOS 8.1 にインストールする手順
mysqlモジュールでDB操作
ブラウザからWebAPIと非同期通信を行う
Vue.js+Express+Socket.IO 最小構成でリアルタイムチャットを作成する

60
65
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
60
65

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?