Socket.io

Ngày đăng: 2024-07-31 15:26:40

Mục lục:

  

 1. Socket.io là gì? Giới thiệu về Socket.io

 2. Tạo môi trường làm việc với Socket.io

 3. Gửi nhận Events trong Socket.io

 4. Broadcasting trong Socket.io

 5. Namespaces & Rooms trong Socket.io

 6. Error Handling & Debugging trong Socket.io

1. Socket.io là gì? Giới thiệu về Socket.io

A. Socket.io là gì ?

Socket.io là một module trong Node.js được phát triển vào năm 2010. Nó được phát triển để sử dụng các kết nối mở để tạo điều kiện giao tiếp thời gian thực, trả về giá trị thực ở tại thời điểm đó. Socket.io cho phép giao tiếp hai chiều giữa máy khách và máy chủ. Giao tiếp hai chiều được bật khi máy khách có Socket.io trong trình duyệt và máy chủ cũng đã tích hợp gói Socket.io

Nó được sử dụng trong việc xây dựng các ứng dụng web real-time cần tốc độ phản hồi ngay lập tức như: chat, trực tiếp bóng đá,.... Socket.io xây dựng dựa trên Engine.IO, đầu tiên nó sẽ thiết lập một kết nối long-polling, sau đó cố gắng nâng cấp lên các kết nối khác tốt hơn giống như WebSocket.

Ngoài Socket.io chúng ta còn có một vài kết nối khác như:

Trong long-polling, client sẽ gửi yêu cầu giống AJAX đến máy chủ. Với mỗi lần nhận được yêu cầu, máy chủ sẽ gửi phản hồi lại nếu & khi có cập nhật mới. Tại đây, clients sẽ liên tục & định kỳ yêu cầu cập nhật từ máy chủ, thông qua các kết nối TCP riêng biệt, làm tắc nghẽn lưu lượng mạng.

Trong short-polling, clients định kỳ gửi yêu cầu đến máy chủ để hỏi xem có gì mới không. Máy chủ không đợi, nhưng gửi lại nếu có cập nhật hoặc chỉ có tin nhắn trống. Ở đây, mạng thậm chí còn tắc nghẽn hơn với các yêu cầu liên tục này, ngay cả khi không có bản cập nhật.

Trong WebSockets, sẽ luôn có một kết nối TCP giữa clients và server. Có luồng dữ liệu hai chiều giữa clients và server cũng như tính chất thời gian thực do luôn kết nối TCP mở. Trong các phương thức, có tiềm năng rất lớn để tăng tốc độ trong WebSockets. Dung lượng phần header của giao thức HTTP là 100 byte, trong khi phần header của socket chỉ là 2 byte. Vì vậy, sau khi sử dụng HTTP ban đầu, Sockets có thể giao tiếp với tài nguyên ít hơn nhiều. Với nhiều số lượng yêu cầu được gửi đến thì nó cũng sẻ làm tăng thời gian phản hồi từ server tới clients.

Socket.io KHÔNG phải là phát triển dựa trên WebSocket. Mặc dù Socket.io thực sự sử dụng WebSocket như một cách để giao tiếp trong một vài trường hợp, Socket.io sẽ bổ sung một số siêu dữ liệu cho mỗi gói: loại gói, không gian tên và id gói khi cần xác nhận thông báo. Đó là lý do tại sao máy khách WebSocket sẽ không thể kết nối thành công với máy chủ Socket.io và máy khách Socket.io cũng sẽ không thể kết nối với máy chủ WebSocket.

B. Socket.io có những gì nổi bật ?

Socket.io được cộng đồng lâp trình viên sử dụng rất nhiều, bởi tốc độ cũng như sự tiện lợi của nó. Socket.io cung cấp cho chúng ta nhiều phương thức cũng như các tính năng nổi bật như: bảo mật, birnary, tự động kết nối, phát hiện ngắt kết nối, ghép kênh, tạo phòng,..

Tính bảo mật

Khi Socket.io xuất hiện, nó sẽ tự động tạo những kết nối bảo mật như:

 

  • Proxy và cân bằng tải.

  • Tường lửa cá nhân và phần mềm chống vi-rút.

Như mình đã đề cập ở trên, Socket.io xây dựng dựa vào Engine.IO, trước tiên nó sẽ khởi chạy phương thức long-polling để kết nối, sau đó sử dụng các phương thức giao tiếp khác tốt hơn giống như Websocket.

Tự động kết nối lại, phát hiện ngắt kết nối

Mặc định, trong quá trình chạy, khi client nếu bị ngắt kết nối, nó sẽ tự động gắng kết nối lại mãi mãi cho tới khi server có phản hổi lại, tính năng này có thể được tùy chỉnh nếu muốn. Ngoài ra, Socket.io còn cung cấp cho chúng ta các events để phát hiện ngắt kết nối giữa client và server, hoặc ngược lại.

Hỗ trợ nhị phân

Socket.io hỗ trợ chúng ta các kiểu mã hóa nhị phân như :

  • ArrayBuffer và Blob trên trình duyệt

  • ArrayBuffer và Buffer trong Node.js

Hỗ trợ tạo kệnh và phòng

Socket.io cũng cho phép tạo ra các kênh riêng biệt, từ đó tạo ra mối quan hệ riêng giữa các phần như mỗi module riêng lẻ hoặc dựa trên các quyền khác nhau. Ngoài ra, còn cho phép bạn tạo ra các phòng khác nhau, những clients có thể được tham gia vào phòng khác nhau. Đây là một tính năng hữu ích để gửi thông báo cho một nhóm người dùng hoặc cho một người dùng nhất định được kết nối trên một số thiết bị chẳng hạn. Với những API đơn giản và thuận tiện giống như:

io.on('connection', function(socket){

  socket.emit('request', /* */); // emit an event to the socket

  io.emit('broadcast', /* */); // emit an event to all connected sockets

  socket.on('reply', function(){ /* */ }); // listen to the event

});

C. Cài đặt Socket.io

Để cài đặt Socket.io trong dự án của mình bạn cần phải cài đặt ở 2 phía đó là server và client. Socket.io sẽ đảm nhận kết nối giữa 2 phía, thông thường các API của 2 phia sẽ tương tự giống nhau.

Socket.io trên server

Đối với server Node.js bạn chỉ cần dùng npm đê cài đặt package có tên socket.io, bạn truy cập vào thư mục dự án và mở terminal :

npm install --save socket.io

Socket.io trên client

Một bản dựng độc lập của clients được hiển thị theo mặc định bởi server tại /socket.io/socket.io.js

Ngoài ra, bạn có thể cài đặt import thư viện này ở cdn , hoặc cài đặt thành các gói như webpack hoặc browserify bằng cách dùng npm:

npm install --save socket.io-client

2. Tạo môi trường làm việc với Socket.io

A. Khởi tạo môi trường làm việc

Để bắt đầu phát triển bằng cách sử dụng Socket.io, bạn cần cài đặt Node.js và npm. Nếu bạn không có những thứ này, bạn cần phải cài đặt Node.js trước tiên. Hãy chắc chắn rằng Node.js và npm được cài đặt bằng cách chạy các câu lệnh :

node -v
npm -v

Nếu máy bạn đã được cài đặt Node.js và có npm thì bạn sẽ nhận được phiên bản của chúng như sau :

socketio can ban khoi tao moi truong png

Cài đặt socket.io

Bạn cần phải cài đặt socket.io ở 2 phía đó là ở server và client:

Cài đặt socket.io trên server

Để cài đặt socket.io trong server bạn tiến hành vào thư mục cần cài và mở terminal gõ dòng lệnh :

npm install ---save socket.io

Cài đặt socket.io trên client

Bạn chỉ cần import thư viện socket.io vào clients, thư viện này sẽ được tạo tự động khi bạn khởi tạo socket.io server

<script src="/socket.io/socket.io.js"></script>         

Cài đặt Express

Ngoài socket.io bạn cần phải cài đặt expressexpress cho phép chúng ta khởi tạo HTTP Server một cách đơn giản và dễ dàng hơn. Để cài đặt express bạn chỉ cần mở terminal lên và gõ dòng lệnh:

npm install ---save express

Sau khi cài đặt thành công, bạn có thể sử dụng express kết hợp với Socket.io trong dự án của mình.

Cài đặt Nodemon

Nodemon là một tiện ích sẽ theo dõi mọi thay đổi trong mã nguồn của bạn và tự động khởi động lại máy chủ.. Điều này giúp ích rát nhiều cho bạn không phải tự refresh server khi chỉnh bất cứ gì đó. Nodemon là một công cụ hữu ích trong quá trình làm việc với các dự án Node.js. Để cài đặt bạn chỉ cần mở terminal và gõ dòng lệnh :

npm install --save-dev nodemon

Nodemon đươc các lập trình viên sử dụng khá nhiều trong quá trình lập trình bởi nó có mội vài điểm nổi bật như :

  • Tự động khởi động lại ứng dụng.

  • Phát hiện phần mở rộng tập tin mặc định để theo dõi.

  • Hỗ trợ mặc định cho node & coffeescript, nhưng dễ dàng chạy bất kỳ tệp thực thi nào (như python, make, v.v.).

  • Bỏ qua các tập tin hoặc thư mục cụ thể.

  • Xem các thư mục cụ thể.

  • Hoạt động với các ứng dụng máy chủ hoặc tiện ích chạy một lần và REPL.

  • Sử dụng trong các ứng dụng node. Nguồn mở và có sẵn trên github.

Thêm vào đó, bạn có thể khởi tạo các biến môi trường trong quá trình làm việc với Node.js. 

B. Khởi tạo Socket.io

Sau khi đã cài đặt các module cần thiết, chúng ta sẽ đi xây dựng một ứng dụng sử dụng Socket.io đơn giản với chỉ chức năng kết nối =))))

Trước tiên, chúng ta sẽ khởi tạo HTTP Server bằng cách tạo một file có tên app.js :

var app = require('express')();

var http = require('http').createServer(app);

var io = require('socket.io')(http);

 

app.get('/', function(req, res){

  res.sendFile(__dirname + '/views/index.html');

});

 

io.on('connection', function(socket){

  console.log('a user connected');

});

 

http.listen(3000, function(){

  console.log('listening on *:3000');

});

Ở trên 3 module chính đó là express, http, và socket.io để khởi tạo server. Khi bạn truy cập vào route /, trình duyệt sẽ nhận về nội dung của file nằm trong đường dẫn /views/index.html

Khi khởi tao server thành công, nó sẽ tự động tạo ra một thư viện cho clients sử dụng ở địa chỉ http://localhost:3000/socket.io/socket.io.js . Đây là thư viện mà socket.io bên server tạo ra dành cho clients. Bạn chỉ cần import thư viên này vào.

Tiếp theo, chúng ta sẽ khởi tạo clients bằng cách tạo files index.html nằm trong thư mục views/

<!DOCTYPE html>

<html lang="vi">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Socket.io titoe.net</title>

</head>

<body>

    <!-- Thêm thư viện socket.io mà server cung cấp -->

    <script src="/socket.io/socket.io.js"></script>

 

    <script>

        //Khởi tạo kết nối

         var socket = io();

    </script>

</body>

</html>

Bây giờ bạn chỉ cần khởi chạy server bằng cách mở terminal và gõ dòng lệnh:

nodemon app.js

khi này bất cứ thay đổi nào từ file server sẽ tự động refresh lại. Truy cập vào đường dẫn http://localhost:3000/, khi này server sẽ nhận được kết nối.

3. Gửi nhận Events trong Socket.io

A. Tìm hiểu về Event trong Socket.io

Socket.io hoạt động dựa trên các sự kiện. Có một số sự kiện dành riêng, có thể được truy cập bằng cách sử dụng đối tượng socket ở phía server như :

  • Connect
  • Message
  • Disconnect
  • Reconnect
  • Ping
  • Join and
  • Leave

Bên phía clients thì chúng ta có các dạng như :

  • Connect
  • Connect_error
  • Connect_timeout
  • Reconnect, etc

Khi nhận được kết nối, Socket.io sẽ tạo ra các event có sẵn để chúng ta có thể dễ dàng bắt lấy các event này và xử lý, ngoài ra bạn có thể gửi dữ liệu từ server sang client hoặc ngược lại bằng cách tạo các event trong connectmessage và disconnect.

Gửi event trong Socket.io

Socket.io cho phép chúng ta có thể gửi event từ server tới clients và ngươc lại, để gửi một event chúng ta sử dụng phương thúc emit :

io.emit([eventName], [data]);

Trong ví dụ bên dưới mình sẽ gửi môt event có tên là infomartion từ server tới clients.

io.on("connection", function(socket) {

  socket.emit("information", { name: "Nguyen Van A", age: 19 });

});

Lúc này tất cả các cliens được kết nối sẽ nhận được events có tên information

socket io events trong socket.io

 

Nhận event trong Socket.io

Bạn cũng có thể nhận dữ liệu từ một event đã tạo trước đó bằng cách sử dụng phương thức on và truyền vào tham số đầu tiên là tên event và tham số tiếp theo là môt callback function để bắt data:

 socket.on([eventName], function (from, msg) {
      //code here
 });

Trong ví dụ này mình sẽ đóng vai là clients và sẽ nhận giá trị mà events information mà server đã khởi tạo phía trên để xử lý :

socket.on('information', function (sender, data) {

        console.log('information : ', data)

})

Ngoài ra, Socket.io cũng cho phép chúng ta gửi các sự kiện đến một socket user nhất định, hay tạo phòng, namespace,..các bạn hãy xem các bài viết tiếp theo trong seri để có thể tìm hiểu rõ hơn nhé. Dưới đây mình sẽ đi xây dựng một chat app đơn giản bằng những kiến thức mà mình giới thiệu ở bên trên.

B. Xây dựng ứng dụng chat đơn giản bằng Socket.io

Cấu trúc thư mục của chat app sẽ bao gồm:

chat-app
----app.js
----views/
---------index.html

Để chuẩn bị bạn cần phải cài đặt một vài module như expresssocket.io cho server bằng cách mở terminal và gõ dòng lệnh :

npm install ---save express socket.io

Khởi tạo HTTP Server kết hợp Socket.io:

var app = require("express")();

var http = require("http").createServer(app);

var io = require("socket.io")(http);

 

app.get("/", function(req, res) {

  res.sendFile(__dirname + "/views/index.html");

});

 

io.on("connection", function(socket) {

   //socket bên phía server ở đây :)))

});

 

http.listen(3000, function() {

  console.log("listening on *:3000");

});

Chat app sẽ sử dụng port 3000 là port chính, nếu bạn gặp lỗi khi khởi chạy thì bạn có thể chuyển sang port khác. Khi truy cập vào route / , clients sẽ nhận được nội dung file index.html trong thư mục views/ đây là cũng là file chúng ta sẽ xử lý bên phía client.

Xây dựng giao diện

Mình sẽ đi xây dựng một giao diện đơn giản, chúng ta sẽ vào thư mục views và tìm file 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; }
      #messages { margin-bottom: 40px }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
    <script src="/socket.io/socket.io.js"></script>
    <script src="https://code.jquery.com/jquery-1.11.1.js"></script>
    <script>
        //Chúng ta sẽ xử lý socket bên phía clients ở đây :))
    </script>
  </body>
</html>

Ngoài việc sử dụng thư viện socket.io cho clients mình còn sử dung jQuery để xử lý DOM đơn giản hơn, bạn có thể tìm hiểu về jQuery để hiểu rõ hơn nhé !

Xử lý chat với Socket.io

Ở file index.js chúng ta sẽ tạo ra sự kiện có tên chat message khi người dùng click vào nút Send và bắt sự kiện trả về từ server :

$(function() {

  var socket = io();

  $("form").submit(function() {

    //Tao sự kiện khi click vào nút send

    socket.emit("chat message", $("#m").val());

    $("#m").val("");

    return false;

  });

 

  //Băt sự kiện từ server

  socket.on("chat message", function(msg) {

    $("#messages").append($("<li>").text(msg));

    window.scrollTo(0, document.body.scrollHeight);

  });

});

Ở file app.js (tức bên phía server) chúng ta sẽ nhận sự lấy sự kiện chat message và gửi trả về sự kiện chat message về cho clients

io.on("connection", function(socket) {

  socket.on('chat message', function(msg){

    io.emit('chat message', msg);

  });

});

Chúng ta sẽ tiến hành khởi chạy dự án bằng cách mở terminal và gõ dòng lệnh :

node app.js

Truy cập vào địa chỉ localhost:3000 chúng ta sẽ thấy thành quả:

chat app using socketio gif

4. Broadcasting trong Socket.io

A. Broadcasting trong Socket.io

Broadcasting có nghĩa là gửi tin nhắn đến tất cả các clients được kết nối. Socket có thể được thực hiện ở nhiều cấp độ. Socket có thể gửi tin nhắn đến tất cả các máy khách(clients) được kết nối, đến các máy khác có không gian cụ thể. Để gửi một sự kiện cho máy khách chúng ta thường sử dụng phương thức io.socket.emit(). Khi sử dụng phương thức này nó sẽ gửi đến tất cả các clients được kết nối.

Khi bạn muốn gửi cho tất cả các clients được kết nối chúng ta sử dụng:

io.on("connection", function(socket) {

   //Gửi cho tất cả client được kết nối

    io.socket.emit('new msg', {msg: '!hello guy =))'})

});

socketio broadcasting png

Khi bạn muốn gửi cho tất cả các clients được kết nối mà ngoại trừ sender chúng ta sử dụng :

io.on("connection", function(socket) {

    socket.broadcast.emit('new msg', {msg: 'msg here!'})

});

Xây dựng ví dụ

Trong phần này chúng ta sẽ đi xây dựng một website đếm người truy cập sử dụng socket.io. Khi có bất cứ kết nối nào thì trình duyệt sẽ hiển thị số kết nối và thông báo người mới join.

Như trong các ví dụ trước, chúng ta sẽ có cấu trúc thư mục quen thuộc:

broadcasting_socket
---app.js
---views/
-------index.html

Cài đặt các module cần tiết trong quá trình khởi tạo server bằng cách mở terminal và gõ dòng lệnh :

npm install --save express socket.io

Chúng ta sẽ làm việc với file app.js bên phía server :

var app = require("express")();

var http = require("http").createServer(app);

var io = require("socket.io")(http);

 

app.get("/", function(req, res) {

  res.sendFile(__dirname + "/views/index.html");

});

var clients = 0;

io.on("connection", function(socket) {

  clients++;

  socket.emit("new msg", { msg: `Hiện tại có ${clients} đang kết nối !!` });

  socket.emit("new noti", { msg: "Một người vừa mới tham gia ! " });

  socket.on("disconnect", function() {

    clients--;

    socket.emit("new noti", { msg: "Một người vừa mới rời đi! " });

  });

});

 

http.listen(3000, function() {

  console.log("listening on *:3000");

});

Bên phía clients chúng ta sẽ xử lý ở file index.html nằm trong thư mục views/

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Socket.io -  Broadcasting</title>

</head>

<body>

    <p id="msg">

 

    </p>

    <div id="noti">

 

    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

    <script src="/socket.io/socket.io.js"></script>

    <script>

        var socket = io()

        socket.on('new msg', function(data) {

            $('#msg').text(data.msg)

        })

        socket.on('new noti', function(data) {

            //console.log(data)

           $('#noti').append(data.msg + '<br>')

        })

    </script>

</body>

</html>

Chúng ta sẽ khởi chạy server và truy cập thử, khởi tạo 3 clients chúng ta sẽ thấy như trong hình:

socketIo broadcasting trong socketio png

Bằng cách này socket sẽ gửi một thông báo "Một người vừa mới truy cập !" cho tất cả mọi người. Bây giờ, nếu chúng ta muốn gửi thông báo đó cho tât cả mọi người, nhưng ngoại trừ người vừa mới truy cập. Chúng ta sẽ sử dụng phương thức socket.broadcast.emit()

Cùng đi sửa một chút ở file app.js để thấy sự khác biệt nhé. Thay phương thức soket.emit('new noti') thành socket.broadcast.emit('new noti'). Trong file app.js chúng ta sẽ sửa thành:

var app = require("express")();

var http = require("http").createServer(app);

var io = require("socket.io")(http);

 

app.get("/", function(req, res) {

  res.sendFile(__dirname + "/views/index.html");

});

var clients = 0;

io.on("connection", function(socket) {

  clients++;

  socket.emit("new msg", { msg: `Hiện tại có ${clients} đang kết nối !!` });

  socket.broadcast.emit("new noti", { msg: "Một người vừa mới tham gia ! " });

  socket.on("disconnect", function() {

    clients--;

    socket.broadcast.emit("new noti", { msg: "Một người vừa mới rời đi! " });

  });

});

 

http.listen(3000, function() {

  console.log("listening on *:3000");

});

Đây là kết quả sau khi sửa:

socketIo broadcasting trong socketio 2 png

Lúc này clients chỉ có thể nhận được thông báo có người truy cập khi đã kết nối, những người mới truy cập sẽ hoàn toàn không nhận được thông báo.

5. Namespaces & Rooms trong Socket.io

A. Namespace trong socket.io

Socket.io cho phép bạn chỉ định "namespace" cho các sockets, có nghĩa là bạn có thể chỉ định các endpoint và đường dẫn khác nhau. Đây là một tính năng hữu ích để giảm thiểu số lượng tài nguyên (kết nối tới TCP) và đồng thời tách biệt mối quan hệ trong ứng dụng của bạn bằng cách phân chia các soket sang các kênh khác.

Thao tác khởi tạo namespaces được thực hiện trên server, tuy nhiên để tham gia một kênh thì clients chỉ cần gửi yêu cầu đến server là có thể tham gia được. Khi chúng ta có một nhóm người dùng thì bạn có thể tạo một namespace để các người dùng trong nhóm có thể kết nối với nhau.

Chúng ta có thể phân chia namespace thành 2 loại chỉnh: mặc định, hoặc tinh chỉnh. Thông thường khi bạn khởi kết nối socket.io thì nó sẽ tạo ra một namespace mặc định, ngoài ra bạn có thể thêm các namespace của riêng bạn.

Namespace mặc định

Namespace root '/' là namespace được chỉ định mặc định, được kết nối bởi các clients nếu namespace không được chỉ cho clients khi kết nối tới server. Tất cả các kết nối đến server sử dụng socket được thực hiện mặc định ở namespace này.

var socket = io();

Phía trên là kết nối tới client mặc định. Tất cả các events trong namespace sẽ được nhận bởi tất cả các io object trong server. Tất cả các ví dụ trừ đầu đến nay mình đểu sử dụng namespace mặc định.

Namespace tùy chỉnh

Chúng ta có thể tạo một namespace tùy chỉnh bằng cách sử dụng phương thức .of trong io như ví dụ bên dưới :

Đây là ví dụ về bên phía server :

const nsp = io.of('/titoe');

nsp.on('connection', function(socket){

  console.log('Có người tham gia');

});

nsp.emit('hi', 'everyone!');

Bên phía clients để tham gia vào namespace chúng ta sẽ gọi như sau:

const socket = io('/titoe');

Lưu ý: Namespace là một giao thức mở rộng của socket.io, khi mở giao thức này sẽ giảm thiếu số lượng kết nối tới một cổng nào đó gây nghẽn và nó không liên quan đến URL của socket mặc định.

B. Rooms trong Socket.io

Trong mỗi một namespace, bạn cũng có thể xác định các kênh tùy ý mà các socket có thể tham gia và rời đi. Các kênh này được gọi là Rooms. Rooms được sử dụng để tiếp tục tách biệt các clients với nhau. Các rooms cũng chia sẻ kết nối socket giống như namespaces. Một điều cần lưu ý trong khi sử dụng rooms là chúng chỉ có thể được tham gia ở phía server.

 

Ở đây chúng ta có 2 phương thức làm việc chính với Rooms bao gồm tham gia vào room và rời khỏi room đó.

Tham gia một Room

Socket.io cho chúng ta phương thức để tham gia vào môt room nào đó, bạn chỉ cần sử dụng phương thức join() :

socket.join(roomName);

Để gửi event vào trong rooms chúng ta sử dụng :

 io.sockets.in(roomName).emit();

Trong đó tham số roomName là tên phòng mà bạn muốn chỉ định.

Rời khởi Room

Ngoài ra bạn có thể rời một Room bằng cách sử dụng phương thức leave()

socket.leave(roomName);

Đây là những phần liên quan đến Room trong Socket, hầu như đây là tất cả những phần quan trọng về room trong Socket.io. 

C. Triển khai ví dụ

Ở đây mình có một ví dụ về namespace và room trong socket.io. Mình sẽ cho clients vào một namespace có tên titoe và thêm tùy chọn thêm và rời rooms có tên titoeRoom nếu người dùng mong muốn. Cấu trúc thư mục quen thuộc có trong mỗi ví dụ:

titoe/

--app.js

--views/

-----index.html

Sau khi triển khai cấu trúc thư mục thành công chúng ta sẽ tiến hành cài các module cần thiết bằng cách mở terminal và gõ dòng lệnh:

npm i --save express socket.io

Ở đây chúng ta sử dụng 2 module chính đó là express và socket.io

Khởi tạo socket.io server

Chúng ta sẽ khởi tạo socket.io server trong file app.js :

var app = require("express")();

var http = require("http").createServer(app);

var io = require("socket.io")(http);

 

app.get("/", function(req, res) {

  res.sendFile(__dirname + "/views/index.html");

});

 

var titoe = io.of("/titoe");

//Chi định namespace có tên /titoe

titoe.on("connection", function(socket) {

  console.log("Một người vừa kết nối.");

 

  //Nhận yêu cầu vào phòng từ clients

  socket.on("join room", function(data) {

    //THam gia phòng

    socket.join("titoeRoom");

    //Trả lại thông báo cho người vào phòng

    socket.emit("notification", "Bạn đã tham gia vào phòng");

 

    //Trả lại thông báo cho tất cả người còn lại trong phòng

   titoe.to("titoeRoom").emit("notification", "Một người đã vào phòng.");

  });

 

  //Nhận yêu cầu rời phòng từ clients

  socket.on("leave room", function(data) {

    //Rời phòng

    socket.leave("titoeRoom");

    //Trả lại thông báo cho người vào phòng

    socket.emit("notification", "Bạn đã rời phòng");

    //Trả lại thông báo cho tất cả người trong phòng

    titoe.to("titoeRoom").emit("notification", "Một người đã rời phòng.");

  });

});

 

http.listen(3000, function() {

  console.log("listening on *:3000");

});

Ở trên mình sử dụng 3 module chính đó là expresshttp, và socket.io để khởi tạo server. Khi bạn truy cập vào route /, trình duyệt sẽ nhận về nội dung của file nằm trong đường dẫn /views/index.html

Tiếp theo, chúng ta sẽ khởi tạo clients bằng cách tạo files index.html nằm trong thư mục views/

<!DOCTYPE html>

<html lang="vi">

 

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Socket.io titoe.net</title>

</head>

 

<body>

    <button id="joinRoom">Vào phòng</button>

    <button id="leaveRoom">Rời phòng</button>

    <div id="notification"></div>

</body>

<!-- Thêm thư viện socket.io mà server cung cấp -->

<script src="/socket.io/socket.io.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

 

<script>

    //Khởi tạo kết nối

    var socket = io('/titoe');

    $('#joinRoom').click(function() {

        //Gọi sự kiện tham gia phòng

        socket.emit('join room', '')

    })

    $('#leaveRoom').click(function() {

        //Gọi sự kiện rời phòng

        socket.emit('leave room', '')

    })

    //Bắt sự kiện notification

    socket.on('notification', function(data) {

        console.log(data)

        $('#notification').append(`<p>${data}</p><br>`)

    })

</script>

 

</html>

Chúng ta thử khởi chạy để thấy rõ hơn. Bây giờ bạn chỉ cần khởi chạy server bằng cách mở terminal và gõ dòng lệnh:

node app.js

Truy cập vào đường dẫn http://localhost:3000/, khi này server sẽ nhận được kết nối:

Bên phía clients cũng sẽ nhận được events từ server và hiển thị ra kết quả:

Ngoài ra bạn có thể cập nhật thêm tính năng mới cho đoạn ví dụ trên như kiểm ta người dùng đã ở trong phòng chưa thì mới hiện button rời phòng,vv...Bạn có thể tham khảo thêm tài liệu ở rang document của Socket.io để có thể hiểu hơn về APIs của nó.

6. Error Handling & Debugging trong Socket.io

A. Error handling

Hầu hết các ví dụ từ đầu seri đến giờ thì chúng ta thường chạy trên local, gần như sẽ không bao giờ gặp các lỗi liên quan đến kết nối, thời gian chờ, v.v. Tuy nhiên, trong xác dự án thực tế, việc xử lý các lỗi đó là vô cùng quan trọng. Do đó, bây giờ chúng ta sẽ cùng nhau tìm hiểu về cách chúng ta có thể xử lý các lỗi kết nối ở phía clients.

API bên phía clients cho chúng ta các sự kiện như :

  • Connect − Khi kết nối thành công

  • Connecting − Khi clients đang kết nối

  • Disconnect − Khi clients bị ngắt kết nối tới server

  • Connect_failed − Kết nối xảy ra lỗi.

  • Error − Khi quá trình gửi event gửi tới server bị lỗi

  • Message − Khi server gửi tin qua send function.

  • Reconnect − Khi đã kết nối lại thành công.

  • Reconnecting − Khi đang kết nối lại

  • Reconnect_failed − Khi kết nối lại bị lỗi.

Mặc định thì khi bị ngắt kết nối tới server, socket.io bên phía clients sẽ kết nối lại liên tuc cho đến khi kết nối thành công. Bạn có thể tinh chỉnh được.

Để xử lý lỗi, chúng ta có thể xử lý các sự kiện này bằng cách sử dụng object socket bên ngoài hàm mà chúng ta đã tạo trên clients:

Ví dụ: Nếu chúng ta có kết nối không thành công, sự kiện 'connect_faild' sẽ được tạo.

socket.on('connect_failed', function() {

   document.write("Xảy ra lỗi kết nối");

})

B. Logging và Debugging

Socket.io sử dụng một module gỡ debug được phát triển bởi chinh tác giả của Express.js, được gọi là debug. Ở phiên bản đầu tiên của Socket thì debug bằng cách log tất cả ra, cách này rất khó debug nên trong phiên bản v1.0 trở đi socket.io bạn có thể debug một cách dễ dàng hơn.

Debug bên phía Server

Cách tốt nhất để debug bên phía server là sử dụng *. Tiến hành debug bằng cách mở terminal và gõ dòng lệnh :

DEBUG=* node app.js

Ở đây mình sẽ tiến hành debug ở file app.js, cách này sẽ tô màu và xuất ra mọi thứ xảy ra các events khiển máy chủ của bạn. Ví dụ, chúng ta có thể xem xét ảnh chụp màn hình sau đây.

socketio debug 1 png

Ở đây bạn sẽ thấy route nào trong express được kích hoạt, hay namespace nào được sử dụng,vv...

Debug bên phía client

Để debug bên phía client bạn chỉ cần đặt một localStorage có tên debug là *, hoặc socket.io-client:socket để giới hạn debug.

Bạn có thể thực hiện bằng cách mở cửa sổ console trên trình duyệt (F12 -> Console) và dán đoạn này vào :

localStorage.debug = '*';

Nếu muốn giới hạn debug thì bạn sử dụng đoạn code này :

localStorage.debug = 'socket.io-client:socket';

Bạn có thể thấy kết quả như trong hình bên dưới :

socketio debug 2 png

 

Về bài trước...

                                 Bài tiếp theo...

 

 


Tài liệu lập trình NodeJS

Bài viết trong cùng chuyên mục

Góc games giải trí



Cờ caro


Butterfly


Lật hình (luyện trí nhớ)

Cờ tướng ONLINE

Xếp hình

Ghép hình

15_PUZZLE

Kill ghosts

Banchim

Planet Defense

Tower game

Tower game

Plapy Bird (NH.Đông)

Vượt chướng ngại vật



0379136392

Thông tin liên hệ: Lê Văn Thuyên - ĐT: 0379136392 ; Gmail: lethuyen0379136392@gmail.com

Comment

 +   Lê Văn Thuyên-0379136392:Cảm ơn quý vị và các bạn đã vào Website của Lê Thuyên! Lê thuyên rất mong nhận được sự góp ý của quý vị và các bạn cho sự phát triển của website này. Xin chân thành cảm ơn!

Trả lời

 *   Dũng Trung-090567448:Lê Văn Thuyên0379136392--->Ok.Anh!

Trả lời

 *   Bé Nguyễn-benguyen@gmail,com:Lê Văn Thuyên0379136392--->Good job!

Trả lời

 +   -:

Trả lời

 +   -:

Trả lời

12214