SignalR adalah library untuk ASP .Net Core yang memudahkan developer untuk menambahkan real-time fungsionalitas pada web application. SignalR menambahkan kemampuan web application untuk mem-push konten atau data ke semua atau sebagian client yang sedang terkoneksi tanpa menunggu client tersebut untuk melakukan request terlebih dahulu. Beberapa fungsi real-time yang bisa diimplementasikan menggunakan SignalR adalah notifikasi instan, aplikasi chat sederhana dan aplikasi yang membutuhkan push notification.
Dengan kapabilitas real-time push konten dari server ke client, maka developer dengan mudah dapat menambahkan fitur – fitur real time ke dalam web application. SignalR menyediakan API yang sederhana untuk membuat koneksi antara client dan server dengan menggunakan RPC (Remote Procedure Call) untuk memanggil fungsi (method) javascript yang ada di client dari code yang ada di server, SignalR juga memelihara koneksi dan secara otomatis meng-handle beberapa event yaitu : OnConnected dan OnDisconnected.
Transport
SignalR menggunakan beberapa mode transport untuk membuat koneksi antara Client dan Server. Beberapa koneksi yang dipakai adalah : HTML 5 Transport (Websocket , Server Sent Events) dan Comet Transport (Forever Frame, Ajax Long Polling), SignalR akan memilih mode transport yang paling optimal untuk digunakan melalui proses seleksi dengan mengecek beberapa kriteria yang harus dipenuhi oleh client dan server. Websocket adalah yang paling optimal, tetapi teknik lain seperti server-sent events dan long-polling bisa juga dipakai bila koneksi websocket tidak tersedia atau client dan web server yang digunakan tidak mendukung teknologi websocket. Jika client menggunakan browser versi lama (internet explorer dibawah versi 8) yang tidak mendukung mode Websocket, SignalR secara otomatis akan menggunakan long-polling atau server-sent event. Teknologi web-server juga menentukan jenis transport yang didukung oleh suatu web aplikasi yang menggunakan SignalR. Selengkapnya ada di sini.
Hubs
Hub adalah jalur komunikasi atau mekanisme tingkat tinggi yang digunakan SignalR untuk mengijinkan client code untuk memanggil method (fungsi) yang ada di server dengan mudah seperti memanggil method yang ada di client itu sendiri, dan sebaliknya server code bisa memanggil method yang ada di client secara langsung. Karena Hub yang mengatur komunikasi, maka untuk meng-handle event OnConnected dan OnDisconnected kita dapat meng-override kedua method tersebut di dalam Hub Class. Di bawah ini adalah contoh ChatHub dengan fungsi sederhana: mengirim pesan ke semua client yang sedang terkoneksi.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ChatHub : Hub | |
{ | |
public void Send(string message) | |
{ | |
Clients.All.SendAsync("SendMessage", Context.User.Identity.Name, message); | |
} | |
public override async Task OnConnectedAsync(){ | |
await Clients.All.SendAsync("SendAction", Context.User.Identity.Name, "joined"); | |
} | |
public override async Task OnDisconnectedAsync(System.Exception exception){ | |
await Clients.All.SendAsync("SendAction", Context.User.Identity.Name, "left"); | |
} | |
} |
Intinya Hub adalah simple POCO yang menurunkan class Hub, method yang bisa di-override adalah OnConnectedAsync dan OnDisconnectedAsync.
Simple Chat App
Untuk mendemonstrasikan SignalR di asp.net core, mari kita buat aplikasi chat sederhana dengan fitur :
- hanya user yang sudah terautentikasi yang bisa mengirim dan menerima chat.
- chat akan di-broadcast ke semua user yang sedang terkoneksi.
Buat project MVC baru menggunakan dotnet cli dan pastikan dikomputer sudah terinstall .net core 2.1 . Buka VSCode dan buat folder baru dengan nama hubs, didalamnya buat class baru yaitu ChatHub.cs copy paste code yang ada di atas.
Kemudian buat controller baru dengan nama ChatController, di dalamnya ada satu method Index yang mengembalikan view. Method ini kosong, karena semua logic untuk mengirim dan menerima chat akan diimplementasikan menggunakan javascript di didalam View Index.cshtml. Untuk penjelasan lebih jelas tentang arsitektur MVC lihat posting saya disini.
Di dalam folder views, tambahkan folder baru Chat dan didalamnya buat file baru Index.cshtml. Untuk menggunakan SignalR javascript client library maka kita harus menginstall npm package @aspnet/signalr, maka itu buka terminal favorit anda dan ketik npm init .
untuk menginisialisasi nodejs project dan npm install @aspnet/signalr
untuk menginstall SignalR module. Setelah terinstall, copy file signalr.js dari folder .node_modules@aspnetsignalrdistbrowser ke folder .wwwrootlibsignalr.
Setelah itu buatlah layout index.cshtml menyerupai chat form, tambahkan referensi javascript signalr.js dan javascript snippet untuk membuat koneksi ke hub yang kita buat sebelumnya. Seperti yang saya jelaskan di atas bahwa client code bisa memanggil server code secara langsung seperti local method yang dibuat langsung di client.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@{ | |
ViewData["Title"] = "Chat"; | |
} | |
<h2>Chat</h2> | |
<div class="container"> | |
<form id="send-form" action="#"> | |
<div class="form-group"> | |
<label>Send a message:</label> | |
<div class="input-group"> | |
<input type="text" id="message-textbox" class="form-control" /> | |
<div class="input-group-btn"> | |
<input type="submit" value="send" id="send-button" class="btn btn-primary" /> | |
</div> | |
</div> | |
</div> | |
<ul id="messages-list"></ul> | |
</form> | |
</div> | |
@section Scripts{ | |
<script src="/lib/signalr/signalr.js" type="text/javascript"></script> | |
<script type="text/javascript"> | |
document.addEventListener('DOMContentLoaded', function () { | |
var sendForm = document.getElementById("send-form"); | |
var sendButton = document.getElementById("send-button"); | |
var messagesList = document.getElementById("messages-list"); | |
var messageTextBox = document.getElementById("message-textbox"); | |
function appendMessage(content) { | |
var li = document.createElement("li"); | |
var bold = document.createElement("b"); | |
bold.className='bold'; | |
bold.innerText=content; | |
li.innerHTML=bold.outerHTML; | |
li.textContent = bold.innerHTML; | |
messagesList.appendChild(li); | |
} | |
var connection = new signalR.HubConnectionBuilder() | |
.withUrl("/hubs/chat") | |
.build(); | |
sendForm.addEventListener("submit", function (e) { | |
var message = messageTextBox.value; | |
messageTextBox.value = ""; | |
connection.send("Send", message); | |
e.preventDefault(); | |
//alert("sent"); | |
}); | |
connection.on("SendMessage", function (sender, message) { | |
appendMessage(sender + ' : ' + message); | |
}); | |
connection.on("SendAction", function (sender, action) { | |
appendMessage(sender + ' ' + action); | |
}); | |
connection.start().then(function () { | |
messageTextBox.disabled = false; | |
sendButton.disabled = false; | |
}); | |
}); | |
</script> | |
} |
Supaya signalr bisa digunakan dalam suatu project ASP .Net Core maka kita perlu register Hubs dan services di Startup.cs. seperti gambar di bawah.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This method gets called by the runtime. Use this method to add services to the container. | |
public void ConfigureServices(IServiceCollection services) | |
{ | |
/// | |
/// sesuai bawaan template project | |
/// | |
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) | |
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, d => | |
{ | |
d.LoginPath = "/account/login"; | |
d.AccessDeniedPath = "/account/denied"; | |
d.Cookie.Name = "chant_signalr"; | |
}); | |
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); | |
services.AddSignalR(); | |
} | |
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | |
public void Configure(IApplicationBuilder app, IHostingEnvironment env) | |
{ | |
/// | |
/// default bawaan template project | |
/// | |
app.UseAuthentication(); | |
app.UseMvc(routes => | |
{ | |
routes.MapRoute( | |
name: "default", | |
template: "{controller=Home}/{action=Index}/{id?}"); | |
}); | |
app.UseSignalR(d=>{ | |
d.MapHub<ChatHub>("/hubs/chat"); | |
}); | |
} |
Setelah itu cobalah compile dan run aplikasi dengan mengetik:
dotnet build
dan
donet run
di dalam terminal.
Source code ada disini.