Chia sẻ thư viện javascript mở rộng khi kết nối tới Hub sử dụng SignalR

Tôi chia sẻ kinh nghiệm và thư viện mở rộng mà tôi viết để kết nối tới Hub sử dụng SignalR. Thư viện do tôi mở rộng thêm với mục đích

  1. 1. Có thể kết nối được tới nhiều Hub
  2. 2. Duy trì được kết nối ổn định: Khi disconnected thì sẽ tự động kết nối trở lại
  3. 3. Có thể đăng ký nhiều sự kiện để nhận data được push từ server gửi về
  4. 4. Khi gửi request lên server Hub thì chỉ gửi được khi đang ở trạng thái kết nối tốt.

Để tải thư viện mở rộng do tôi viết các bạn có thể tải tại đây.

function Hub(hubUrl, hubName)
{
    this.onOk = function (func) { if (state == 2) func(); };
    this.onBeforeStart = function () { };
    this.start = function() {/* Code coe */ };
}

Phần mở rộng tôi viết gồm hubUrl, hubName là trỏ đến địa chỉ Hub cần kết nối tới. this.onOk là phương thức đảm bảo đang ở trạng thái kết nối mới thực hiện func (một hành động nào đó). Với class Hub tôi đã xử lý hết các sự kiện khi mất kết nối, đang kết nối và kết nối

// Nếu bị mất kết nối thì 2s sau sẽ kết nối lại
$this.hub.connection.disconnected(function ()
{
    console.log("disconnected");
    state = 1;
    var t = setInterval(function () { $this.doHubStart(true); clearInterval(t); }, $this.timeout);
});
$this.hub.connection.reconnecting(function ()
{
    state = 1;
    console.log("reconnecting");
});

// Đã được kết nối lại
$this.hub.connection.reconnected(function ()
{
    console.log("reconnected");
    var t = setInterval(function () { $this.doHubStart(true); clearInterval(t); }, $this.timeout);
});

Nếu bị mất kết nối, thì sau khoảng this.timeout (mặc định 2000ms) sẽ thực hiện kết nối lại.

Hub.ActionRegistry = function ()
{
    this.registry = function (func) { /* Code code */ }
    /* Code Code */
}

Với Hub.ActionRegistry được dùng để đăng ký các hành động sau khi nhận dữ liệu được push từ server gửi về. Tại sao tôi lại viết class này, vì tôi hướng tới có thể nhiều nơi, nhiều module mà cũng muốn nhận dữ liệu push về mà không phải lúc nào cũng phải sửa lại phương thức nhận dữ liệu tại client của Hub. Điều này cũng đồng nghĩa với việc lúc nào module nào dùng thì có thể đăng ký nhận dữ liệu.

Sau đây là code mẫu tôi viết cho chương trình chat đơn giản về sử dụng thư viện mở rộng trên

Tán gẫu nào
Trước tiên bạn cũng cài đặt SignalR và gắn thẻ script ở client
<script src='/signalr/hubs'></script> <!-- file js mà hub sinh ra -->
<script src='Hub.js'></script>        <!-- Thư viện mở rộng của tôi -->
Code server để định nghĩa Hub
public class ExampleHub : Hub
{
    public void ClientSendMessage(string userName, string msg, string color)
    {
        userName = userName.Trim();
        if (userName.IsNull()) return;            

        msg = msg.Trim();
        if (msg.IsNull()) return;            

        var data = new { userName, avatar = userName.First(), msg, time = DateTime.Now.ToString("HH:mm dd/MM/yyyy"), color };

        Clients.AllExcept(Context.ConnectionId).receiveMessage(data, false);
        Clients.Client(Context.ConnectionId).receiveMessage(data, true);
    }
}
Code javascript tại client để kết nối tới Hub
function ExampleHub()
{
    $.extend(this, new Hub("", "exampleHub"));

    this.actionReceiveMessage = new Hub.ActionRegistry();

    this.onBeforeStart = function ()
    {
        var $this = this;

        // Client        
        this.hub.client.receiveMessage = function (data, right) 
        { 
            $this.actionReceiveMessage.do(function (func) { func(data, right); }); 
        };

        // Server
        this.startDone = function () { };
        this.clientSendMessage = function (userName, message, color)
        {
            this.onOk(function ()
            {
                $this.hub.server.clientSendMessage(userName, message, color);
            });
        }
    };
}

Ở đây các bạn có thể thấy ExampleHub kế thừa tới Hub và gán 2 giá trị: hubUrl = "" (Do server của hub nằm ngay tại server web của tôi) và hubName = "exampleHub".

Ở phía xử lý client có this.actionReceiveMessage là đối tượng đăng ký nhận hành động muốn xử lý data gửi về từ serverClient muốn giao tiếp gửi request tới server thì thông qua this.onOk để luôn đảm bảo chỉ thực hiện request khi ở trạng thái kết nối ổn định.

Và cuối cùng là giao diện hiển thị tôi định nghĩa một BoxChat như sau
function BoxChat()
{              
    this.ws = null; // là một instance của ExampleHub
    this.area = null;
    var template = null;

    var colors = { 0: "bg-danger text-white", 1: "bg-success text-white", 2: "bg-primary text-white", 3: "bg-warning text-white", 4: "bg-secondary text-white", 5: "bg-dark text-white", 6: "bg-orangered text-white" };
    var names = { 0: "Sơn20", 1: "Dũng", 2: "Việt Anh", 3: "TuhiKing", 4: "Tàn Long", 5: "ButaKing", 6: "Osoft" };

    var color = null;

    this.start = function ()
    {
        color = colors[Core.random(6)];

        var $this = this;
        template = this.area.find("[data-form=template] .direct-chat-msg");
        var userNameInput = this.area.find("[name=userName]");
        var messageInput = this.area.find("[name=message]").focus();
        var butonSend = this.area.find("[data-form=button]");

        userNameInput.val(names[Core.random(6)] + "." + Core.random(20)); // Tạo một tên ngẫu nhiên
        butonSend.click(function ()
        {                        
            var userName = userNameInput.val();
            if (userName == "") { Core.alert("Vui lòng nhập tên tài khoản để tán gẫu"); return; };

            var message = messageInput.val();
            if (message == "") { Core.alert("Vui lòng nhập nội dung để tán gẫu"); return; };

            $this.ws.clientSendMessage(userName, message, color);
        });
        messageInput.keypress(function (event)
        {
            if (event.keyCode == "13")
            {
                butonSend.click();
                return false;
            }
        });

        var formChat = this.area.find("[data-form=chat]");
        this.ws.actionReceiveMessage.registry(function (data, right)
        {
            var chatItem = template.clone();
            chatItem.find("[data-chat]").each(function () { $(this).html(data[$(this).attr("data-chat")]); });
            chatItem.find("[data-chat=avatar]").addClass(data.color);
            if (right) chatItem.addClass("right");
            formChat.append(chatItem);

            formChat.scrollTop(formChat[0].scrollHeight);
            messageInput.val("").focus();
        });
    }
}

Tại hàm start của BoxChat tôi đăng ký hành động khi có message gửi về thì hiển thị nội dung tin nhắn lên. Như đã nói ở trên, actionRegistry giúp đăng ký hành động nhận push từ server ở mọi module mà mình muốn mà không cần phải sửa lại hàm ở client trong hub.

Cuối cùng là khai báo và sử dụng
var ws = new ExampleHub();
ws.timeout = 2000; // Mặc định
ws.start();

var boxChat = new BoxChat();
boxChat.ws = ws;
boxChat.area = $("article");
boxChat.start();

// Ví dụ viết code đăng ký thêm một hành động nhận dữ liệu từ server push về
// Thì hiển thị một notify bên góc phải trên cùng màn hình
// Để cho thấy là có thể đăng ký sự kiện nhận dữ liệu ở mọi nơi.
ws.actionReceiveMessage.registry(function (data, right)
{
    new PNotify({ target: $("article"), text: data.userName + ":" + data.msg, type: "success", delay: 1000 });
});

Tại bài viết này tôi vẫn đang sử dụng asp.net SignalR mà chưa chuyển sang asp.net Core SignalR. Do chưa đủ điều kiện về vật chất, hạ tầng và nhất là hệ thống phần mềm hiện tại của tôi vẫn đang viết trên asp.net. Tuy nhiên với cách làm này của tôi thì chuyển sang asp.net Core tôi cũng sẽ làm tương tự. Và đây là chia sẻ nhỏ mà tôi đã làm trong thực tế.

Gửi cảnh báo khi nhân viên thêm phiếu chi với một mục đích chi nào đó bị quá giới hạn cho phép mà quản lý đã cấu hình

Click vào cảnh báo ở góc phải bên dưới màn hình xem ngay được nội dung cảnh báo

Tại nội dung cảnh báo. Click xem chi tiết phiếu để xem nhân viên đã thêm chi cho những mục đích gì

Chúc các bạn lập trình ngày càng tốt hơn. Nếu có thắc mắc các bạn hãy để lại bình luận nhé. Xin cảm ơn smiley

Sơn 20

Nếu bạn thấy nội dung chia sẻ này có ích với bạn hãy Donate để tạo động lực cho tôi viết các bài viết tiếp theo nhé. Cảm ơn nhiều !!!!

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

Hướng dẫn gửi email bằng code C#. Cấu hình tài khoản gmail để gửi email từ phần mềm.

Sử dụng thư viện SmtpClient để gửi email. Cấu hình tài khoản gmail ở trạng thái kém bảo mật để có thể gửi email từ phần mềm.

02/12/2020 Xem chi tiết
Các hướng đi cho lập trình viên khi lựa chọn ngôn ngữ lập trình.

Mình thì lựa chọn phát triển web nên đã chọn chuyên sâu về HTML, Css, Javascript, ASP.NET, SQL

23/11/2020 Xem chi tiết
Mật khẩu kém bảo mật được sử dụng phổ biến trong năm 2020

Bất ngờ với mật khẩu 123456 lại đứng top đầu danh sách. Cứ bảo sao tài khoản hay bị hack. Đúng là sai lầm và chủ quan.

20/11/2020 Xem chi tiết
Xây dựng khung phần mềm trên nền Web giao diện Desktop Window

Đã xây dựng gần như xong khung, chỉ việc viết module business để phát triển phần mềm trên nền tảng Web giao diện Window.

30/10/2020 Xem chi tiết
Tôi đã thiết kế ra design pattern Trứng có trước hay Gà có trước như thế nào

Về ý tưởng này tôi đã thực hiện khoảng 5,6 năm trước do tham gia vào dự án mà xây dựng các khối độc lập nhưng lại có tính năng tương tự nhau

19/10/2020 Xem chi tiết
Chia sẻ một số hiệu ứng Hover hữu ích khi làm Frontend viết bằng css

Gồm các hiệu ứng Hover ZoomIn, Hover Fade, Hover Blur, Hover Zoomout, Hover Mask, Hover Over Text, Hover Fall, Hover Blurout

16/10/2020 Xem chi tiết

Bài viết khác

Tại sao code của tôi thường ngắn gọn như vậy

Khi bắt tay vào thực hiện các yêu cầu tôi thường phân tích kỹ và code trừu tượng.

15/09/2020 Xem chi tiết
Hướng dẫn sử dụng bootstrap tourist để làm trợ giúp cho phần mềm

Làm trợ giúp, hướng dẫn cho khách hàng sử dụng website một cách đơn giản nhất. Tôi cũng đã ứng dụng cho phần mềm của mình.

12/09/2020 Xem chi tiết
Hướng dẫn sử dụng Jquery plugin Lazy Load everything

Đây là plugin tôi chỉnh sửa lại từ thư viện jquery.lazyload.js để từ đó có thể lazy với mọi phần tử và không chỉ riêng cho sử dụng lazy image.

10/09/2020 Xem chi tiết
Thư viện Linq.js trong javascript

Thư viện này cung cấp đầy đủ các phương thức như .NET 4.0 và mở rộng thêm nhiều phương thức khác

10/09/2020 Xem chi tiết
Hướng dẫn sử dụng Jquery Plugin Hotkeys - Tạo phím nóng trên trình duyệt web

Thư viện của tác giả Tzury Bar Yochay được viết từ năm 2010

06/09/2020 Xem chi tiết
Hướng dẫn sử dụng Timer trong Javascript

Định nghĩa đối tượng Timer tương tự như trong WinForm C# để thực hiện task vụ theo chu kỳ bằng Javascript

01/09/2020 Xem chi tiết
{"nalias":"chia-se-thu-vien-javascript-mo-rong-khi-ket-noi-toi-hub-su-dung-signalr","lang":"2","cattype":"0","catId":"3","UrlEngine":"UrlNewsEngine","site":"1"}