Merhaba bu yazı dizisinin konusu ASP.NET CORE ve SignalR kullanarak gerçek zamanlı işlemleri gerçekleştirmek. SignalR ASP.NET dünyasında çokça kullanılan basit ve kullanışlı bir websocket paketi. Bu yazı dizisinin amacı baştan sona bir mesajlaşma sistemi geliştirmek fakat tabiki ilk yazımızın konusu daha basit olacak.
Websocket gerçek zamanlı işlemler için en iyi çözüm olan web protokollerinden biri ve websitelerde bildirim & mesajlaşma gibi bir çok olayda kullanılıyor.
HTTP ve WebSocket arasındaki fark nedir?
Çok önceden geliştirdiğim uygulamalarda gerçek zamanlı verileri almak için saniyede bir HTTP isteği atar ve güncel veriyi çekerdim 😊
Tabiki bu yanlış bir yöntem ve gereksiz bir işlem. Sunucuya yük bindiriyor. Bunun yerine olay olunca haberdar edilen iki yönlü bir protokol olan WebSocket’i tercih etmek çok daha mantıklı.
WebSocket iki yönlü bir iletişim protokolü, olay olduğunda bağlı olan client’lerin hepsini veya istediğimiz client’i bilgilendirebilmemizi sağlıyor.
Öncelikle bu yazıda amacımız temel leri öğrenmek, yani signalr ile websocket bağlantısını kurmak ve chatroom mantığıyla yani gönderdiğimiz mesajın herkes’e ulaştığı bir senaryoyu gerçekleştirmek.
Gereksinimler
- İsteyen kullanıcı odaya girebilir, herhangi bir kimlik belirtmek zorunda değildir.
- Giren kullanıcı mesaj gönderebilir ve bu mesaj herkese iletilir.
İlk aşamada bu şekilde basit tutacağım fakat ilerleyen yazılarda tam işlevli ve güvenli bir mesajlaşma sistemine dönüştüreceğim.
Back-End Kısmı
Kullanılacak Paketler
Öncelikle ASP.NET Core projemizde signalr paketimizi nuget ile projemize dahil ediyoruz. Ben consol komutunu palaşacağım ama siz paket yöneticisini de kullanabilirsiniz.
dotnet add package Microsoft.AspNetCore.SignalRBen .NET 10 için hazırlıyorum bu yazıyı.
Projede WEB.API namespace kullanacağım.
Hub (Bağlantı Noktası) Oluşturma
Paketimizi yüklediğimize göre öncelikle websocket uygulamamız için bir bağlantı noktası oluşturmalıyız. Bunun için SignalR da hazır gelen Hub sınıfını kullanacağım.Bu sınıfı kalıtım yaparak kendi Hub yani bağlantı noktamızı oluşturacağız ve içerisine metodlarımızı ekleyeceğiz.
Hubs/MessageHub.cs Son hali
using Microsoft.AspNetCore.SignalR;
namespace WEB.API.Hubs
{
public class MessageHub : Hub
{
public async Task MessageSent(string message)
{
await Clients.All.SendAsync("MessageSend", message);
}
}
}
Burada basitçe MessageSend isminde bir olay tanımladık ve bu olayımızdan gelen mesajı tüm kullanıcılara gönderdik.
Kritik satır:
await Clients.All.SendAsync("MessageSend", message);Hub oluşturduğumuza göre sırada bu hub’u Program.cs dosyamız üzerinden DI’ yapısına kaydetmek var.
Servis Kaydı ve Aktifleştirme
Program.cs Son hali
using WEB.API.Hubs;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
builder.Services.AddSignalR();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.UseStaticFiles(); // ndex.html dosyamızın tanınması için statik dosya desteğini aktifleştirdik
app.MapHub<MessageHub>("/hubs/message-room"); // bağlantı noktamızı aktifleştirdik.
app.Run();
Kritik Noktalar:
Burada kritik satırlar öncelikle servis kaydı satırı. Bu satır ile SignalR servisini kaydettik.
builder.Services.AddSignalR(); // SignalR servisini kaydettik.İkinci kritik satırlar ise statik dosya kullanımını ve hub bağlantı kontasını aktif ettiğimiz satırlar.
app.UseStaticFiles();
app.MapHub<MessageHub>("/hubs/message-room");Bu sayede tarayıcıda room.html dosyasını kullanabileceğiz ve /hubs/message-room bağlantı noktamız websocket bağlantısı için aktif olacak.
Back – End Mesaj Gönderme Endpointi
Mesaj gönderirken kullanacağımız DTO’muzu yanımlıyoruz.
SendMessageDTO.cs
namespace WEB.API.DTOs
{
public class SendMessageDTO
{
public string Message { get; set; }
}
}
Controllers/MessageRoomController.cs Son hali
using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.Mvc;
using WEB.API.Hubs;
using WEB.API.DTOs;
namespace WEB.API.Controllers
{
[ApiController]
[Route("api/message-room")]
public class MessageRoomController : ControllerBase
{
private readonly IHubContext<MessageHub> _hubContext;
public MessageRoomController(IHubContext<MessageHub> hubContext)
{
_hubContext = hubContext;
}
[HttpPost]
[Route("create")]
public async Task<IActionResult> CreateMessage( [FromBody] SendMessageDTO dto)
{
await _hubContext.Clients.All
.SendAsync("MessageSend",dto.Message);
return Ok(new { Message = "Message Sent" });
}
}
}
Kritik noktalar
DI aracılığıyla tanıttığımız hub’u kullanıyoruz.
private readonly IHubContext<MessageHub> _hubContext;
public MessageRoomController(IHubContext<MessageHub> hubContext)
{
_hubContext = hubContext;
}Tüm kullanıcılara mesaj gönderiyoruz:
await _hubContext.Clients.All
.SendAsync("MessageSend",message);Frontend Kismi
Backend kısmında gerekli değişiklikleri yaptığımıza göre artık front-end kısmına geçebilriz. Kullanıcımız için basit bir mesaj listesi ve mesaj gönderme butonu yapıyoruz. Hemen ardından da official signalr kütüphanesi ile zaten adresini aktifleştirdiğimiz bağlantı noktasına bağlanıyoruz.
wwwroot/room.html son hali
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Message Room</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/9.0.6/signalr.min.js"></script>
<script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>
</head>
<body>
<div class="card">
<h1>Messajlar</h1>
<ul class="messages">
</ul>
<textarea id="messageForm"></textarea>
<input type="submit" id="sendMessageButton" value="Send Message" />
</div>
<script>
const connection = new signalR.HubConnectionBuilder()
.withUrl("/hubs/message-room")
.build();
connection.on('MessageSend', function (message) {
addMessageToList(message);
});
connection.start();
function addMessageToList(message) {
$('.messages').append("<li>" + message + "</li>");
}
$('#sendMessageButton').click(function () {
$.ajax({
url: "/api/message-room/create",
method: "POST",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ message: $("#messageForm").val() }),
success: function () {
$("#messageForm").val(""); // temizle
},
error: function (xhr) {
console.log("Error:", xhr.status, xhr.responseText);
}
});
});
</script>
<style>
.card {
display: flex;
flex-direction: column;
gap: 10px;
max-width: 500px;
margin: 0 auto;
background: #ddd;
border: 1px solid #ccc;
border-radius: 5px;
padding: 10px;
min-height: 100px;
}
.messages {
background: #ccc;
border-radius: 5px;
padding: 0;
display: flex;
flex-direction: column;
gap: 10px;
}
.messages li {
list-style: none;
padding: 5px;
}
#sendMessageButton {
background: #0094ff;
color: #fff;
border: 0;
padding: 10px;
}
</style>
</body>
</html>
Kritik Noktalar:
Bağlantı oluşturma kodu:
const connection = new signalR.HubConnectionBuilder()
.withUrl("/hubs/message-room")
.build();
connection.on('MessageSend', function (message) {
addMessageToList(message);
});Bu kod aracılığıyla /hubs/message-room adresine yani odamıza bağlandık ve MessageSend olayını dinliyoruz mesaj geldiği zaman addMessageToList fonksiyonuna aktarıyoruz mesajımızı ve o da mesaj listemize ekliyor.
Mesaj göndermek için ise:
$('#sendMessageButton').click(function () {
$.post('api/message-room/create', { message: $('#messageForm').val() })
});Butonumuz’a click eventi gönderildiğinde ilgili endpoint aracılığıyla mesajımızı backend’e gönderiyoruz o da tüm kullanıcılar ile paylaşıyor.
Özet
Bu yazımızda bisit bir mesajlaşma odası uygulaması geliştirdik.ASP.NET Core Web API + SignalR kullandık. Şimdilik gönderenin bile belli olmadığı bir sistem geliştirdik. İlerleyen yazılarda adım adım bunu ilerleteceğim.
Projenin son hali github da her bölüm için ayrı branch açacağım.
Bu yazının branch’ı
https://github.com/gokhancelebi/ChatRoomExampleProject/tree/bolum-1

Bir yanıt yazın