ASP.Net Web Programlama

Signalr .net Core

Signalr uygulamasının .net core ortamında oluşturulması ve IIS ortamında yayınlandığı esnada karşılaştığım root sorununun çözümüne dair bilgiler paylaşacağım.

Microsoft.AspNetCore.SignalR nuget kütüphanesi projeye eklenir.

Projeye client side library ekliyoruz unpkg seçilerek @microsoft signalr.js eklenir

Solution alanında projeye sağ tıklanarak owin startup.cs eklenir.

//Program.cs
public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseUrls(
                    "http://0.0.0.0:5000"
                )
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseSockets()
                .UseKestrel();
    }
//Startup.cs
public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            /*services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(options =>
                {
                    options.LoginPath = "/Account/Login/";
                });*/
            services.AddSession(options=> {
                options.Cookie.Name = ".metinyakarnet.Session";
                options.IdleTimeout = TimeSpan.FromHours(1);
                options.Cookie.HttpOnly = true;
                options.Cookie.IsEssential = true;
            });
            services.AddCors(action =>
            {
                action.AddPolicy("allowCors", builder =>
                {
                    builder
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowAnyOrigin()
                    .AllowCredentials();
                });
            });
            
            services.AddMvc()
                .AddSessionStateTempDataProvider(); 
            services.AddSignalR(
                hubOptions =>
                {
                    hubOptions.EnableDetailedErrors = true;
                    hubOptions.KeepAliveInterval = TimeSpan.FromMinutes(10);
                });
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            //app.UseAuthentication();
            var cookiePolicyOptions = new CookiePolicyOptions
            {
                MinimumSameSitePolicy = SameSiteMode.Strict,
                HttpOnly= Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy.Always,
                Secure= CookieSecurePolicy.Always
            };
            app.UseCookiePolicy(cookiePolicyOptions);

            app.UseStaticFiles();
            app.UseWebSockets();
            app.UseSession();
            app.UseSignalR((routes) =>
            {
                routes.MapHub<ChatHub>("/chathub");
            });

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
//Hubs/Chatup.cs

public class ChatHub : Hub
    {
        public async Task JoinChat(string user)
        {
            await Clients.All.SendAsync("JoinChat", user);
            
        }

        public async Task LeaveChat(string user)
        {
            await Clients.All.SendAsync("LeaveChat", user);
        }

        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }

        public object GetConnectionValues()
        {
            return new {
                ConnectionId= Context.ConnectionId
            };
        }
    }
//Views/Shared/__layout.cshtml
<head>
    <title>metinyakar.net signalr .net core test</title>
    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/@@microsoft/signalr/dist/browser/signalr.js"></script>
    <script src="~/lib/signalr/hubs"></script>
</head>
<body>
    @RenderBody()

    <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <script src="~/js/site.js"></script>

    @RenderSection("Scripts", required: false)
</body>
//chat.cshtml

<div id="maindiv">
    <div id="chatstatus">
        Sunucuya bağlanılamadı!
    </div>
    <div id="chatarea">
        <ul id="chats"></ul>
    </div>
    <div id="actarea">
        <input type="hidden" id="userInput" value="web" />
        <textarea id="message"></textarea>
        <button id="sendButton">Gönder</button>
    </div>
</div>

<script src="~/js/chatSignal.js"></script>
//chatSignal.js
var url ="/chatHub";
var connection = new Object();
var user = document.getElementById("userInput").value;
var message = document.getElementById("message");
window.onload = function () {
    var usrprompt = document.getElementById("userInput");
    usrprompt.value = prompt("Kullanıcı adınızı seçiniz");
    //var connection = new signalR.HubConnectionBuilder().withUrl(url).build();

    connection = new signalR.HubConnectionBuilder()
        .configureLogging(signalR.LogLevel.Error | signalR.LogLevel.Critical)
        .withUrl(url, {
            skipNegotiation: false,
            transport: signalR.HttpTransportType.WebSockets | signalR.HttpTransportType.LongPolling
        })
        .build();

    document.getElementById("sendButton").disabled = true;

    var showstatus = document.getElementById("chatstatus");
    connection.on("ReceiveMessage", function (user, message) {
        var msg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
        var encodedMsg = "<div class='chatItem_user'>" + user + ":</div> <div class='chatItem_msg'>" + msg + "</div>";
        var li = document.createElement("li");
        li.innerHTML = encodedMsg;
        document.getElementById("chats").appendChild(li);
    });
    connect(connection);
    connection.onclose(function (e) {
        console.log("reconnected at " + new Date().toString());
        connect(connection);
    });
    document.getElementById("sendButton").addEventListener("click", function (event) {
        sendmsg();
        event.preventDefault();
    });
    document.getElementById("message").addEventListener("keyup", function (event) {
        if (event.keyCode === 13) {
            sendmsg();
        }
    });
    function sendmsg() {
        connection.invoke("SendMessage", user, message.value);
        message.value = "";
        message.focus();
    }


    async function connect() {
        connection.start().then(function () {
            var but = document.getElementById("sendButton");
            but.disabled = false;
            connection.invoke("JoinChat", user);
            showstatus.innerText = "Sunucuya bağlandı... ";
            showstatus.style.color = "green";
            connection.invoke("GetConnectionValues")
                .then(function (values) {
                    window.sessionStorage.setItem("cid", JSON.stringify(values));
                    window.NTalkConectionId = values.connectionId || JSON.parse(window.sessionStorage.getItem("cid")).connectionId;
                });
        }).catch(function (err) {
            console.log(err);
            showstatus.innerText = err;
        });
    }
}
//IIS'de yayınlandığında ortaya çıkan root sorunu ile ilgili hub'a ulaşamama durumunda çalışılan path'i ekrana yazdırarak chatsignal.js dosyasındaki url düzenlenebilir.
ViewData["PathBase"] = Request.PathBase.ToString();

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir