Cấp bậc tác giả:

DOTNET

Chat Room với Asp.Net SignalR

Được viết bởi QuangIT ngày 29/09/2013 lúc 05:30 PM
Gần đây, Microsoft đã thêm một số tính năng mới trong ứng dụng web ASP.NET Framework. SignalR là một trong những tính năng nổi bật với runtime real build ứng dụng ví dụ như ứng dụng xã hội trực tuyến, trò chơi đa người dùng, tin tức thời tiết,...
  • 0
  • 16690
Tải tệp tin: Click ở đây

Chat Room với Asp.Net SignalR

Giới thiệu 
Gần đây, Microsoft đã thêm một số tính năng mới trong ứng dụng web ASP.NET Framework. SignalR là một trong những tính năng nổi bật với runtime real build ứng dụng ví dụ như ứng dụng xã hội trực tuyến, trò chơi đa người dùng, tin tức thời tiết,... Trong thời gian thực ứng dụng máy chủ đẩy nội dung cho client kết nối ngay lập tức trở nên có sẵn. Nó cung cấp ASP.NET API đơn giản để tạo máy chủ đến client gọi thủ tục từ xa (RPC) gọi chức năng JavaScript trong trình duyệt của máy khách từ phía máy chủ. NET. 

Các ứng dụng web hoạt động trong mô hình Request-Response. Trình duyệt và đại diện người sử dụng khác có những yêu cầu và máy chủ web cung cấp đáp ứng yêu cầu đó. Phản hồi sẽ được gửi đến địa chỉ nhận được cung cấp trong các yêu cầu của đại diện người dùng. Trong mô hình máy chủ này khôngthể làm phản hồi mà không có yêu cầu. Vì vậy, trong máy chủ ứng dụng thời gian thực đẩy nội dung/dữ liệu cho máy khách mới có sẵn. Bạn có thể đạt được tính năng này sử dụng ASP.NET SignalR API.

Bắt đầu
Để giải thích SignalR Web API, trong bài này tôi sẽ tạo ra ứng dụng chat, nơi bạn có thể trò chuyện nhóm và trò chuyện riêng tư với người dùng. Bạn cần Visual Studio 2012 Express Development để tạo ra dự án này. Bạn có thể biết thêm chi tiết về http://www.asp.net/signalr

Tạo một dự án ứng dụng web mới trong visual studio và trong Solution Explorer, Kích chuột phải vào Project, chọn Add> New Item và chọn mục SignalR Hub Class. Đặt tên lớp và nhấn nút Add. Nó sẽ thêm lớp Hub, các reference và script yêu cầu.

addHubClass.png

Bạn có thể xem thêm kịch bản và tham chiếu bằng cách mở rộng nút ‘Scripts’ and ‘References’

reference.png

Đăng ký URL Hub
Sử dụng SignalR API, chúng ta cần phải đăng ký URL ~/signalr/hubs. Thêm tập tin global.asax trong íolution và trong đăng ký phương thức Application_Start sử dụng lệnh RouteTable.Routes.MapHubs().

 public class Global : System.Web.HttpApplication
 {

    protected void Application_Start(object sender, EventArgs e)
    {
        // Register the default hubs route: ~/signalr/hubs
        RouteTable.Routes.MapHubs();
    }

 }   

Lớp Hub

Lớp ChatHub phải được thừa kế từ lớp Microsoft.AspNet.SignalR.Hub. Class Hub cho thấy một số thuộc tính và phương thức. Sử dụng thuộc tính máy khách, bạn có thể giao tiếp với máy khách được kết nối. Bạn có thể nhận được thông tin của máy khách ai đang gọi phương thức sử dụng Context và bạn cũng có thể quản lý các nhóm sử dụng thuộc tính Groups.

public abstract class Hub : IHub, IDisposable
{

  public HubConnectionContext Clients { get; set; }
  public HubCallerContext Context { get; set; }
  public IGroupManager Groups { get; set; }

  public virtual Task OnConnected();        
  public virtual Task OnDisconnected();       
  public virtual Task OnReconnected();

}
Lớp dẫn xuất có thể ghi đè lên OnConnected, OnDisconnected, rất hữu ích để thực hiện một số hành động trên những sự kiện này. Lớp ChatHub có nguồn gốc từ lớp Hub và chúng ta sẽ thảo luận về phương thức của nó trong phần sắp tới.

 public class ChatHub : Hub
 {
          
    public void Connect(string userName);

    public void SendMessageToAll(string userName, string message);

    public void SendPrivateMessage(string toUserId, string message);

    public override System.Threading.Tasks.Task OnDisconnected();

    .
    .
    .

 }   

Máy Khách gọi phương thức Connect khi muốn tham gia phòng chat. Cho gửi tin nhắn trong phòng chat để tất cả các máy khách kết nối, nó gọi SendMessageToAll, Đối với trò chuyện riêng với máy khách gọi phương thức SendPrivateMessage.

Proxy ở phía Máy khách

Thêm trang mới index.html trong Solution và thiết lập các tham chiếu của JQuery, SignalR và sinh tự động các hub.

 <script src="Scripts/jquery-1.8.2.min.js"></script>

 <!--Reference the SignalR library. -->
 <script src="Scripts/jquery.signalR-1.0.0.js"></script>

 <!--Reference the autogenerated SignalR hub script. -->
 <script src="signalr/hubs"></script>   
    
Ở phía máy khách mà bạn cần để tạo ra hub proxy và bắt đầu proxy. Bạn có thể tạo hub proxy sử dụng $.connection.yourHubClass và sau đó bắt đầu hub sử dụng phương thức $.connection.hub.start().

 <script type="text/javascript">

  $(function () {

     // Declare a proxy to reference the hub. 
     var chatHub = $.connection.chatHub;

     registerClientMethods(chatHub);

     // Start Hub
     $.connection.hub.start().done(function () {

        registerEvents(chatHub)

     });

  });

 </script>  
    
Import được chú ý ở đây là quy ước đặt tên được sử dụng trong tự động tạo ra quyền hub. Tôi đặt tên lớp của chúng ta là ChatHub tại máy chủ trong trường hợp camel nhưng ở phía máy khách, tôi đang nhận được nó trong trường hợp camel thấp như $.connection.chatHub

Kết nối với Chat Room

connect.png

Người sử dụng trong phòng chat kết nối với các phòng chat bằng cách thông qua tên của mình và trên các kết nối thành công. Phương thức đầu tiên của chúng ta trong lớp ChatHub là Connect.

public void Connect(string userName)
 {

    var id = Context.ConnectionId;

    if (ConnectedUsers.Count(x => x.ConnectionId == id) == 0)
    {

        ConnectedUsers.Add(new UserDetail { ConnectionId = id, UserName = userName });

        // send to caller
        Clients.Caller.onConnected(id, userName, ConnectedUsers, CurrentMessage);

        // send to all except caller client
        Clients.AllExcept(id).onNewUserConnected(id, userName);

    }

 }    

Nhận được id kết nối của máy khách kêu gọi phương thức Connect sử dụng thuộc tính Context.ConnectionId. Kiểm tra id trong danh sách máy khách kết nối hiện tại. Nếu nó không tồn tại thì thêm nó vào danh sách. Bây giờ chúng ta cần phải làm hai bước. Trước tiên chúng ta phải gửi danh sách các máy khách hàng đã kết nối và danh sách bài viết mới cho máy khách muốn kết nối và thứ hai, chúng ta đã thông báo cho máy khách kết nối khác về người tham gia mới.

Vì vậy, chúng ta có thể dễ dàng gọi phương thức phía máy khách muốn kết nối bằng thuộc tính Clients.Caller.

// send to caller
  Clients.Caller.onConnected(id, userName, ConnectedUsers, CurrentMessage);

Thông báo cho máy khách kết nối khác về máy khách mới, nhưng chúng ta không muốn gọi phương thức của máy khách mới được kết nối. Sử dụng thuộc tính AllExcept của Clients, trong đó có thể bao gồm một số máy khách theo mong muốn.

 // send to all except caller client
 Clients.AllExcept(id).onNewUserConnected(id, userName);  

Xác định/đưa ra các phương thức phía máy khách đang được gọi bằng mã phía máy chủ bằng cách báo cáo Clients.Caller.onConnected (...) và Clients.AllExcept(id).onNewUserConnected(...). Bạn có thể xác định phương thức của bạn sử dụng chatHub.client.yourMethodName tại phía máy khách.

// Calls when user successfully logged in
 chatHub.client.onConnected = function (id, userName, allUsers, messages) {

    .
    .
    .

 }

 // On New User Connected
 chatHub.client.onNewUserConnected = function (id, name) {

    AddUser(chatHub, id, name);
 }     

Từ phía máy khách, bạn có thể gọi các phương thức phía máy chủ sử dụng chatHub.server.yourMethod trên trang web.  

chatHub.server.connect(name);    
 
Gửi tin nhắn trong phòng Chat

chat_room.jpg

Trong chat chính thông điệp nhập bởi người dùng được phát sóng cho tất cả các máy khách được kết nối. Trên máy chủ bên trong lớp ChatHub viết SendMessageToAll và tin nhắn quảng bá sử dụng phương thức Clients.All.messageReceived. messageReceived là một phương thức phía khách hàng.

 public void SendMessageToAll(string userName, string message)
 {
    // store last 100 messages in cache
    AddMessageinCache(userName, message);

    // Broad cast message
    Clients.All.messageReceived(userName, message);
 }   
 

Về phía máy khách tiếp xúc với phương thức messageReceived và trong phương thức này chỉ cần thêm tin trong vùng trò chuyện sử dụng JQuery.

chatHub.client.messageReceived = function (userName, message) {

    AddMessage(userName, message);
 
 }  

Sau khi viết phía máy khách và phương thức phía máy chủ, bây giờ chúng ta phải đăng ký sự kiện click nút về phía máy khách và khi người dùng bấm nút sẽ gọi phương thức phía máy chủ sendMessageToAll, mà phát sóng thông điệp tới máy khách tất cả các kết nối.

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

     var msg = $("#txtMessage").val();
     if (msg.length > 0) {

         var userName = $('#hdUserName').val();

         chatHub.server.sendMessageToAll(userName, msg);
        
         $("#txtMessage").val('');
     }
 });    

Trò chuyện riêng tư

chat_riengtu.jpg

Bạn cũng có thể bắt đầu trò chuyện riêng tư bằng cách nhấp đúp vào tên người dùng được kết nối. Trong cuộc trò chuyện riêng không gửi tin nhắn đến tất cả các máy khách được kết nối. Trong trò chuyện cá nhân chỉ có hai máy khách có thể gửi/nhận mỗi tin nhắn khác. Vì vậy, để gửi tin nhắn gửi tin sẽ gọi máy chủ bên phương thức sendPrivateMessage. Và trong phương thức này, chúng ta gửi tin nhắn choâmý khách khác sử dụng phương thức Clients.Client(toUserId).sendPrivateMessage(..).

 public void SendPrivateMessage(string toUserId, string message)
 {

    string fromUserId = Context.ConnectionId;

    var toUser = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == toUserId) ;
    var fromUser = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == fromUserId);

    if (toUser != null && fromUser!=null)
    {
        // send to 
        Clients.Client(toUserId).sendPrivateMessage(fromUserId, fromUser.UserName, message); 

        // send to caller user
        Clients.Caller.sendPrivateMessage(toUserId, fromUser.UserName, message); 
    }

 } 
   

Ngắt kết nối 
Trên thân của trình duyệt SignalR API gọi phương thức OnDisconnected. Ghi đè lên phương thức này trong lớp ChatHub và trong phương thức này loại bỏ các máy khách bị ngắt kết nối từ danh sách bộ nhớ cache và gửi thông báo cho máy khách kết nối khác.

public override System.Threading.Tasks.Task OnDisconnected()
 {
     var item = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);
     if (item != null)
     {
         ConnectedUsers.Remove(item);

         var id = Context.ConnectionId;
         Clients.All.onUserDisconnected(id, item.UserName);

     }

     return base.OnDisconnected();
 }    

Nguồn bài viết: DOTNET.VN

BÌNH LUẬN BÀI VIẾT

Bài viết mới nhất

LIKE BOX

Bài viết được xem nhiều nhất

HỌC HTML