Chat application with NodeJS, Socket.IO, Mysql and Express framework

Nội dung:

  • Giới thiệu NodeJS
  • Sơ lược về Socket và SocketIO
  • Chat application
  • Chat application advance
  • Kết luận
  • Tài liệu tham khảo

1. Giới thiệu NodeJS

Nodejs là gì?

Nodejs là một nền tảng được phát triển độc lập được xây dựng trên javascript runtime của chrome’s mà chúng ta có thể xây dựng được ứng dụng mạng nhanh chóng và dễ dàng mở rộng.

Nodejs được xây dựng và phát triển từ năm 2009 và được bảo trợ từ công ty Joyent. Khả năng đáp ứng của nodejs là rất nhanh bởi nodejs được viết hầu hết bởi ngôn ngữ C.

Những ứng dụng nào có thể viết bằng nodejs?

Các chương trình như các kênh chat với tốc độ thời gian thực runtime.
Các chương trình upload file
Các máy chủ quảng cáo
Các dịch vụ đám mây
Và bất kỳ ứng dụng dữ liệu thời gian thực nào.

Những kết luận sai lầm về nodejs cần tránh.

Nodejs không phải là một web framework mà là một nền tảng để phát triển các ứng dụng.

Nodejs không giành cho những người mới.

Chúng ta phải lập trình từ những tầng rất thấp ví dụ như chúng ta phải nhận các requests từ client xử lý dữ liệu và response trả về cho client, thêm vào đó nodejs yêu cầu cần chúng ta phải thành thạo ngôn ngữ javascript có thể cần 1 chút html và css để chúng ta phát triển các ứng dụng web bằng nodejs

Nodejs không hỗ trợ chúng ta lập trình đa luồng tức là không tạo ra nhiều luồng hay tiến trình để xử lý đoạn mã của chúng ta 1 cách đồng thời. Các bạn hãy tưởng tượng nodejs như là 1 máy chủ đơn luồng.

Bài sau ta sẽ tìm hiểu cơ chế thực thi của nodejs và khái niệm làm cho nodejs trở nên nhanh và mạnh mẽ

Như vậy chúng ta đã hiểu cơ bản nodejs là gì?

Lý do gì để tự tin sử dụng nodejs?

Các ứng dụng nodejs được viết hoàn toản bởi ngôn ngữ javascript và javacript thì có 1 số đặc tính làm cho nó rất khác so với các ngôn ngữ lập trình động khác, cụ thể là nó không có khái niệm đa luồng.

Nodejs là một môi trường pt đa nền tảng phía server và các ứng dụng mạng.

Nodejs cho phéo chúng ta chạy các ứng dụng ở trên các hệ điều hành khác nhau.

Như Mac OS X, Window, Linux.

Mô hình nodejs hoàn toàn dựa trên các sự kiện và các cơ chế non-blocking điều này làm cho nodejs trở nên nhẹ nhanh và hiệu quả ở các ứng dụng free-time chạy đa nền tảng và đa thiết bị.

Cho tới thời điểm này số lượng thư viện miễn phí trên NPM đã lên tới con số hơn 95000 modules và chưa dừng lại ở con số này.

Nếu chúng ta sử dụng CSDL noSQL ví dụ như mongodb thì nodejs cho phép chúng ta sử dụng dữ liệu JSON trực tiếp như nhau ở client , server và CSDL mà ko cần chuyển đổi gì cả.

Ông lớn nào đang sử dụng nodejs?

Có rất nhiều công ty lớn đã sử dụng nodejs để phát triển ứng dụng của họ ở mức độ bộ phận hoặc toàn bộ như:

Trước khi đọc tiếp bài viết này, Nếu bạn là người mới và chưa biết gì về nodejs thì hãy tham khảo link sau để có những kiến thức cơ bản.

http://freetuts.net/hoc-nodejs/nodejs-can-ban

2. Sơ lược về Socket và SocketIO :

Trước tiên, Socket là 1 công nghệ. Đừng nhầm lẫn giữa Socket.IO và Socket. Socket.IO không phải là mô hình Socket duy nhất hiện nay, và cũng không phải là mô hình web socket duy nhất hiện nay. Socket là cách bạn tổ chức mô hình client-server để một trong 2 bên luôn trong tình trạng sẵn sàng trả lời bên kia và ngược lại. Để đảm bảo việc này, kết nối giữa Client và Server phải ở trạng thái “keep-alive” và phải luôn xảy ra quá trình đồng bộ giữa Client-Server. Socket sẽ mang lại khả năng trả lời tức thì từ một trong 2 bên khi bên kia đưa ra một sự kiện, thay vì phải thực thi lại một loạt các thủ tục kết nối phức tạp như trước, và ứng dụng của bạn sẽ trở thành ứng dụng thời gian thực ví dụ: Yahoo Messenger, Skype v.v… đều là các ứng dụng được xây dựng theo mô hình Socket.

Trong lập trình web trước đây, việc xây dựng client-server theo mô hình socket phải thông qua các phần mềm thứ 3. Vì mô hình socket không phù hợp với các ngôn ngữ lập trình Server như: PHP, ASP.NET, JSP v.v… Các ngôn ngữ này luôn làm việc theo cách: Die ngay connection khi Server trả lời Client xong. Tuy nhiên, mình nhấn mạnh: Chúng ta có thể làm được web-socket với bất kỳ ngôn ngữ lập trình nào. Chỉ có điều, với các ngôn ngữ cũ, việc làm này cần bạn phải am hiểu các giao thức http, tcp; hiểu thế nào là 1 request header, v.v…

Nodejs là một nền tảng mới, xây dựng thuần túy bằng javascript. Đây là một điểm lợi thế của Node.js để lập trình web-socket:

Thứ nhất: javascript là ngôn ngữ lập trình hướng sự kiện, mà trong lập trình thời gian thực, cách tiếp cận bằng lập trình sự kiện là cách tiếp cận khôn ngoan nhất.

Thứ hai: Node.js chạy non-blocking việc hệ thống không phải tạm ngừng để xử lý xong một request sẽ giúp cho server trả lời client gần như ngay tức thì.

Thứ ba: lập trình socket yêu cầu bạn phải xây dựng được mô hình lắng nghe - trả lời từ cả 2 bên. Nói khác đi, vai trò của client và server phải tương đương nhau, mà client thì chạy bằng javascript, nên nếu server cũng chạy bằng javascript nữa, thì việc lập trình sẽ dễ dàng và thân thiện hơn.

Chính vì những đặc điểm này, socket.io ra đời. Tuy nhiên, khi bạn thực sự am hiểu về Node.js, http request header, bạn hoàn toàn có thể viết một socket cho riêng mình.

3. Chat application.

Sau khi đã tìm hiểu về node.js và socket.io thì bây giờ, chúng ta sẽ ứng dụng để làm 1 demo nhỏ. Trong hướng dẫn này chúng ta sẽ tạo một ứng dụng chat cơ bản.

Giới thiệu

Viết một ứng dụng chat với hầu hết các web application như LAMP(PHP) là điều rất khó khăn. Nó đòi hỏi việc polling server cho những thay đổi, theo dõi timestamps và nó chậm hơn rất nhiều so với mong đợi của người sử dụng.

Socket có thể giải quyết các vấn đề xung quanh, nhưng vấn đề mà hầu hết các hệ thống chat thời gian thực được kiến trúc. Cung cấp kênh thông tin liên lạc giữa client và server.

Điều này có nghĩa là server có thể push message đến client, bất cứ khi nào bạn viết một message, ý tưởng là client sẽ nhận được message và push nó đến tất cả các client đang có kết nối khác.

The web framework

Mục tiêu đầu tiên là thiết lập 1 trang html, nó sẽ chứa 1 form để nhập nội dung message và nơi chứa list message chat giữa các client. Chúng ta sẽ sử dụng Express framework để thực hiện việc này. Hãy chắc chắn rằng NodeJS đã được cài đặt trên máy của bạn nhé.

Đầu tiên chúng ta sẽ tạo file package.json nơi sẽ mô tả project của chúng ta. Chúng ta sẽ tạo một thư mục cho project này (chẳng hạn tôi đặt là chat-example).

{
"name": "chat-example",
"version": "1.0.0",
"description": "chat-examole",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "PhongNX",
"license": "ISC"
}

Bây giờ chúng ta sẽ cài đặt module mà chúng ta cần. sử dụng npm install --save:

npm install --save express@4.15.2

Bây giờ express đã được cài đặt, chúng ta có thể tạo một tập tin index.js mà nó sẽ thiết lập ứng dụng của chúng ta

var app = require('express')();
var http = require('http').Server(app);

app.get('/', function(req, res){
  res.send('<h1>Hello world</h1>');
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});
  • Express khởi tạo app như 1 function handle mà bạn có thể cung cấp cho máy chủ HTTP (Như ở dòng 2)
  • Chúng ta định nghĩa function get, sử lý xự kiện khi chúng ta di chuyển đến trang home của website.
  • Tạo http server lắng nghe trên cổng 3000

Bây giờ, nếu chúng ta chạy file index.js, chúng ta sẽ thấy như sau:

Và nếu chúng ta chạy trên trình duyệt với đường dẫn http://localhost:3000

Serving HTML

Để ứng dụng của chúng ta dễ hình dung hơn. Tôi sẽ tạo riêng 1 file html cho phần giao diện.

Trong file index.js chúng ta sẽ thay thế đoạn code này, để gọi đến trang index.html

app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});

Và bây giờ chúng ta tạo 1 trang index.html như bên dưới
<!doctype html>

<html>
  <head>
    <title>Socket.IO chat</title>
    <style>
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
  </body>
</html>

Bây giờ chúng ta thự hiện reset server (nhấn Ctr C và chạy lại lệnh node index.js). Kết quả là

Integrating Socket.IO

Socket.IO gồm có hai phần:

  • Một Server tích hợp(hoặc gắn kết) các Node.js HTTP Server: socket.io
  • Một thư viện client mà tải ở phía trình duyệt: socket.io-client
    Trong development, socket.io phục vụ các client tự động cho chúng ta, như chúng ta sẽ thấy sau đây, vì vậy bây giờ chúng ta chỉ cần cài đặt một module:
npm install --save socket.io

Bây giờ chúng ta sẽ sửa file index.js

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
  console.log('a user connected');
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

Tiếp theo, add nội dung dưới đây vào file index.html trước thẻ

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io();
</script>

Đó là tất cả những gì cần thiết để load các socket.io-client, và sau đó là kết nối. Bây giờ nếu có một người dung nào kết nối đến server. Một thông báo sẽ xuất hiện ở console “a user connected”.

Thử mở nhiều tab, bạn sẽ thấy nhiều thông điệp.

Mỗi soket cũng có sự kiến ngắt kết nối đặc biệt.

io.on('connection', function(socket){
  console.log('a user connected');
  socket.on('disconnect', function(){
    console.log('user disconnected');
  });
});

Emitting events

Ý tưởng chính là khi người dung nhập một tin nhắn và nhấn Enter/Send SocketIO sẽ bắt sự kiện này và gửi lên seser xử lý, sau đó trả về lại cho người dung, nhưng người đang connect đến server nội dung message.

Bây giờ chúng ta sẽ sửa file index.html như bên dưới

<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
  $(function () {
    var socket = io();
    $('form').submit(function(){
      socket.emit('chat message', $('#m').val());
      $('#m').val('');
      return false;
    });
  });
</script>

Trong file index.js, chúng ta them xử lý out message cho client

io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    console.log('message: ' + msg);
  });
});

Broadcasting

Mục tiêu tiếp theo là để chúng ta phát ra sự kiện từ máy chủ đến các người sử dụng còn lại.

Để gửi một sự kiện để tất cả mọi người, Socket.IO cho chúng ta io.emit:

io.emit('some event', { for: 'everyone' });

Nếu bạn muốn gửi message đến tất cả các client, ngoại trừ người nào đó

io.on('connection', function(socket){
  socket.broadcast.emit('hi');
});

Trong trường hợp này, để đơn giản, tôi gửi đến tất cả các client kể cả người gửi.

io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    io.emit('chat message', msg);
  });
});

Về phía client, tôi sẽ tạo một xử lý bắt sự kiến mà server trả message về.

<script>
  $(function () {
    var socket = io();
    $('form').submit(function(){
      socket.emit('chat message', $('#m').val());
      $('#m').val('');
      return false;
    });
    socket.on('chat message', function(msg){
      $('#messages').append($('<li>').text(msg));
    });
  });
</script>

Và cuối cùng ứng dụng chat đơn giản của chúng ta đã hoàn thành. Cùng xem kết quả nhé.

4. Chat application advance

Vậy là chúng ta đã cơ bản xây dựng được 1 ứng dụng chat, phải nói là cực kỳ đơn giản, thô sơ. Chỉ bao gồm chức năng chính là chat giữa các client với nhau.

Bây giờ, để nâng cao, phát triển thêm các tính năng cho ứng dụng này tôi có các gợi ý sau

  • Sử dựng cơ sở dữ liệu mysql để lưu thông tin đăng nhập của client (bao gồm loginID và pass)
  • Mỗi khi có client join vào group chat, hiện thông báo cho các thành viên khác cùng biết
  • Hiện tên của mỗi client riêng biệt tại ô chat để biết đó là message của client nào
  • Nếu đăng nhập group chat thất bại, có thể tùy ý xử lý như là di chuyển đến trang Error v.v
  • Thêm các biểu tượng cảm xúc, có thể chèn vào ô chat.
    Phía trên là nhưng gợi ý để chúng ta có thể phát triển them cho ứng dụng này.

Kết nối với Mysql

Để thực hiện kết nối đến Mysql, đầu tiên chúng ta sẽ tạo một table trên cơ sở dữ liệu Mysql như sau

Để cài đặt module mysql trên nodejs sử dụng lệnh sau

npm install mysql@2.10.2

Source code

Và đây là source code đầy đủ cho các tính năng mở rộng trên. Các bạn có thể tham khảo và bổ sung thêm nhưng tính năng cần thiết để hoàn thiện ứng dụng nhé.

https://github.com/phongnx1/NodeJS_ChatApp

Demo application

Khởi động server

Join chat group

Trường hợp Login name không tồn tại trong DB

Thông báo khi có client nào đó join vào group

Và kết quả nhiều client cùng chat

5. Kết luận.

Bài viết này cơ bản đã giới thiệu đến các bạn về nodejs, sử các module trong nodejs như thế nào. Sơ lược về SocketIO, Express framework và demo một ứng dụng chat mô phỏng. Bài viết cũng cung cấp cho các bạn cách kết nối với cơ sở dữ liệu Mysql, các bạn có thể phát triển các ứng dụng khác sau này.

6. Tài liệu tham khảo