Nội dung
- shares
- Facebook Messenger
- Gmail
- Viber
- Skype
Bài hôm nay mình xin hướng dẫn các bạn tạo ứng dụng chat đơn giản với socket.io bạn cần chuẩn bị kiến thức đôi chút về Node.js và module Socket.IO
Giới thiệu
Viết ứng dụng chat cho thành viên và khách hàng tương tác trên ứng dụng web được trú trọng hiện nay ở một vài web công ty lớn. Như cách làm truyền thống sử dụng LAMP (php) để phát triển công cụ chat tích hợp vào web là rất khó. Nó liên quan tới gửi dữ liệu đến server và theo dõi timestamps nghiêm ngặt tuy nhiên ứng dụng chạy khá chậm chạp. Đây không phải là giải pháp tốt.
Socket là một giải pháp thay thế, module này trong node.js được phát triển cho cấu trúc của ứng dụng chat chuyên nghiệp. Cung cấp 2 đường giao tiếp song song giữa client và server. Nghĩa là server có thể push messages đến mọi clients có kết nối tới server.
Web framework
Chúng ta sẽ viết website bằng ngôn ngữ javascript của node.js với module express. Ví dụ đầu tiên mình tạo một trang HTML đơn giản chứa form nhập tin nhắn bởi người dùng và hiển thị danh sách messages. Có 2 cách, thứ nhất bạn tạo 1 page riêng chạy trên server khác và kết nối vào server nodejs hoặc tạo page chạy trực tiếp trên node.js đó chính là web framework express
mà mình giới thiệu. Trước tiên hãy đảm bảo bạn đã cài đặt Node.js
Mọi dự án node.js đều tạo file manifest package.json
, files này nhận dạng loại ứng dụng node.js. Chép vào nội dung sau:
{ "name": "socket-chat-example", "version": "0.0.1", "description": "my first socket.io app", "dependencies": {} }
Lưu ý: tạo nodejs project mới không có thư mục nào bên trong, tránh tự tạo folder named “node_modules”.
Chúng ta cài đặt dần riêng lẻ các modules và cập nhật vào file cấu hình package.json
Cài express vào project với lệnh sau:
npm install --save express
Để lưu thông tin node.js module bạn sử dụng tham số --save
trong lệnh cài đặt.
Trong khi đợi express cài đặt, chúng ta tạo file chạy chính index.js
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 quản lý đối tượng giao thức http có nhiệm vụ trao đổi giữa server và trình duyệt và hiển thị nội dung HTML tới người dùng trình duyệt thông qua hàm app.get
theo địa chỉ trang, truyền hàm callback bạn có làm việc với 2 đối tượng gửi dữ liệu vào server (request) và trả dữ liệu về trình duyệt (response). Ở đoạn code trên, khi mở địa chỉ trang chủ: localhost:3000 sẽ hiển thị chuỗi “Hello world”.
Nếu bạn chạy node index.js
sẽ thấy nội dung print trong console như thế này.
và bây giờ bạn mở trình duyệt gõ địa chỉ localhost:3000 kết quả là:
Nếu bạn viết HTML ngay trên file node thì quá khổ cực, do đó mới ra đời express bạn tạo file .html ngoài và gửi file này vào trình duyệt sử dụng hàm sendFile
app.get('/', function(req, res){ res.sendFile('index.html'); });
Nội dung index.html
<!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>
Khỏi động lại index.js, bằng lệnh ngắt Control +C và chạy lại node index.js
, load lại trình duyệt bạn thấy nội dung đã cập nhật thêm, giống thế này:
Chú ý:
Mọi thay đổi của file node.js bạn phải restart lại file server .js mới có tác dụng.
Tích hợp Socket.IO
Socket.io là module cho phép bạn gửi và dữ liệu từ server tới client và ngược lại. Tiếp theo cài đặt module socket.io
npm install --save socket.io
Lệnh trên tiến hành cài đặt dependency socket.io và thêm vào manifest package.json
. Sửa lại 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('index.html'); }); io.on('connection', function(socket){ console.log('a user connected'); }); http.listen(3000, function(){ console.log('listening on *:3000'); });
Khi một user mới kết nối server hay chạy địa chỉ localhost:3000 sẽ mở kết nối mới vào sự kiện connection. Khởi tạo instance socket.io và liên kết tới đối tượng http. Nghĩa là socket.io liên quan đến sự kiện của http.
Tiếp đến, mở index.html và thêm các dòng sau trước thẻ < /body >
<script src="/socket.io/socket.io.js"></script> <script> var socket = io(); </script>
Để tạo đối tượng socket.io tại client, cho phép gửi dữ liệu vào server chúng ta cần chèn thư viện socket.io vào thẻ script. Vì trang HTML host trực tiếp ở server node.js, nên địa chỉ thư viện javascript socket.js có dạng: /socket.io/socket.io.js
. Chú ý: trong server các bạn khai báo dạng relative URL.
Truy cập file socket.io.js trên trình duyệt, nếu cho phép sử dụng cổng ví dụ test trên localhost thì địa chỉ đầy đủ ở trên là http://localhost:3000/socket.io/socket.io.js. Nhớ URL có kèm theo port.
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
Nếu ở host khác, ví dụ cài node.js trên heroku, chúng ta không viết thêm port vào địa chỉ heroku app, cổng mặc định của app là 80 và vấn đề này mình có liệt kê những lưu ý khi sử dụng host heroku để tạo ứng dụng node.js. Bạn trỏ vào nội dung file socket.io.js với địa chỉ app như bình thường. Ví dụ:
<script src="http://mighty-retreat-4105.herokuapp.com/socket.io/socket.io.js"></script>
Gọi Hàm io()
trả về đối tượng socket trong client.
Ok, Khởi động lại server và xem console khi mở một vài tabs website mới bạn sẽ nhìn thấy nội dung print trong console.
Mỗi socket tương ứng với 1 client kết nối vào server, sẽ có các sự kiện theo dõi như disconnect,..sự kiện này sẩy ra khi client ngắt kết nối bằng cách thoát trang hoặc reload page lúc này kích hoạt đồng thời 2 sự kiện disconnect
và connection
.
io.on('connection', function(socket){ console.log('a user connected'); socket.on('disconnect', function(){ console.log('user disconnected'); }); });
Gửi dữ liệu giữa client và server
Socket.IO có ý tưởng cho phép bạn gửi và nhận mọi sự kiện bạn tạo ra. Đơn giản là phóng dữ liệu từ server đến client theo tên sự kiện, mỗi tin nhắn được gửi đi theo nhóm sự kiện bạn đặt tên, và client nhận được cũng có thể gửi lại cho server sử lý.
Dữ liệu gửi đi có thể là chuỗi, đối tượng JSON và thậm trí hỗ trợ binary data. Ví dụ trong ứng dụng chat chúng ta có thể gửi hình ảnh, file đính kèm.
Ví dụ sau đây, ý tưởng đơn giản là khi người gửi tin nhắn từ client thông qua sự kiện “chat message”, server theo dõi và nhận nội dung tin nhắn tại sự kiện này. Để đính mọi nội dung vào sự kiện và gửi đến client/server chúng ta sử dụng hàm emit
.
<script src="/socket.io/socket.io.js"></script> <script src="http://code.jquery.com/jquery-1.11.1.js"></script> <script> var socket = io(); $('form').submit(function(){ socket.emit('chat message', $('#m').val()); $('#m').val(''); return false; }); </script>
Server index.js
sẽ xuất nội dung của sự kiện chat message
.
io.on('connection', function(socket){ socket.on('chat message', function(msg){ console.log('message: ' + msg); }); });
Xem Kết quả như trong video dưới:
Chú ý: dữ liệu của sự kiện thuộc về mỗi client riêng biệt, khi bạn gửi từ server đến client giống như chat tin nhắn cá nhận, socket.io sẽ chỉ gửi đến user đó hoặc server cũng có thể gửi đến mọi client đang kết nói tới. Bằng cách sử dụng đối tượng broadcast, tất cả clients đều nhận được tin nhắn từ server.
io.on('connection', function(socket){ socket.broadcast.emit('hi'); });
Và client cũng được phép gửi tới mọi clients khác cùng một lúc thông qua đối tượng io
. Ví dụ dưới, client gửi đi đến các clients khác từ chính sự kiện “chat message” và chính client này cũng sẽ nhận được tin nhắn của nó. Lưu ý: dữ liệu tin nhắn gửi đi theo sự kiện nhất định, không thì không sự kiện nào nhận được, ví dụ trên là sai bạn phải đính nội dung muốn gửi vào sự kiện , chẳng hạn: socket.broadcast.emit('chat message','hi');
io.on('connection', function(socket){ socket.on('chat message', function(msg){ io.emit('chat message', msg); }); });
Chúng ta khai thác nội dung tin nhắn bắt trên client , sau đó hiển thị lên trình duyệt.
<script> 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>
Hoàn thành ứng dụng chat trong bài viết này, khoảng 20 dòng code bạn đã có thể tạo riêng cho mình ứng dụng chat cho website rồi.
Kết nối nodejs ngoài server.
Ở ví dụ, tôi tạo client ngay trong node.js server, tuy nhiên nếu bạn dùng node.js làm server độc lập với server lưu trữ web của bạn đang chạy trên internet thì bạn cần kết nối tới server node.js
Trường cài node.js trên heroku.
<script src="http://mighty-retreat-4105.herokuapp.com/socket.io/socket.io.js"></script> <script> //test socket.io var vcn_socket=io.connect('http://mighty-retreat-4105.herokuapp.com:80'); #chỉ định port 80, vì có thể ăn theo port của browser mà k pải là 80 ... </script>
Lưu ý: bạn nên chỉ định port mặc định 80 cho ứng dụng heroku, tránh trường hợp website của bạn chạy ngoài 80 io.connect
sẽ ăn theo port của trình duyệt.
Ví dụ Chạy nodejs trên localhost bạn rõ ràng phải khai báo port của địa chỉ server rồi.
<script> var socket=io.connect('http://localhost:3000'); </script>
Một số lỗi sẩy ra trên server node.js
Để tránh lỗi “xhr request timeout” thử thêm dòng vào file server .js
//thêm 2 dòng này io.set('transports', ['xhr-polling']); io.set("polling duration", 10);
Ví dụ thiết lập cấu hình cho socket.io bởi hàm configure
.
io.configure(function () { io.set("transports", ["xhr-polling"]); io.set("polling duration", 10); });
Chúc bạn thành công!
Hãy cho mình biết suy nghĩ của bạn trong phần bình luận bên dưới bài viết này. Hãy theo dõi kênh chia sẻ kiến thức WordPress của Hoangweb trên Twitter và Facebook
- shares
- Facebook Messenger
- Gmail
- Viber
- Skype