Search code examples
asp.netsignalrrazor-3

SignalR Live Chat (automatically get username)


I've been following the SignalR Live Chat tutorial (http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/tutorial-getting-started-with-signalr-20), and it works great! All though, to try and learn a bit myself, I've been trying to configure it a bit to match what I need.

I'm trying to remove the username prompt and make it automatically get the logged in users username. Only logged in users can access the Chat page, so.

As you can see, I'm trying to get the name through ChatHub.cs, but I can't figure out how to make that all work with the SignalR JavaScript.

Thank you in advance.

Chat.cshtml:

@{
    Page.Title = "Chat";
}

<div class="content">
    <h2>@Page.Title</h2>

    <style type="text/css">
        .container {
            background-color: #99CCFF;
            border: thick solid #808080;
            padding: 20px;
            margin: 20px;
        }
    </style>

    <div class="container">
        <input type="text" id="message" />
        <input type="button" id="sendmessage" value="Send" />
        <input type="hidden" id="displayname" />
        <ul id="discussion"></ul>
    </div>

    <script src="~/assets/js/jquery-2.1.1.min.js"></script>
    <script src="~/Scripts/jquery.signalR-2.1.2.min.js"></script>
    <script src="~/signalr/hubs"></script>
    <script type="text/javascript">
        $(function () {
            // Declare a proxy to reference the hub.
            var chat = $.connection.chatHub;
            // Create a function that the hub can call to broadcast messages.
            chat.client.broadcastMessage = function (name, message) {
                // Html encode display name and message.
                var encodedName = $('<div />').text(name).html();
                var encodedMsg = $('<div />').text(message).html();
                // Add the message to the page.
                $('#discussion').append('<li><strong>' + encodedName
                    + '</strong>:&nbsp;&nbsp;' + encodedMsg + '</li>');
            };
            // Get the user name and store it to prepend to messages.
            $('#displayname').val(prompt('Enter your name:', ''));
            // Set initial focus to message input box.
            $('#message').focus();
            // Start the connection.
            $.connection.hub.start().done(function () {
                $('#sendmessage').click(function () {
                    // Call the Send method on the hub.
                    chat.server.send($('#displayname').val(), $('#message').val());
                    // Clear text box and reset focus for next comment.
                    $('#message').val('').focus();
                });
            });
        });
    </script>


</div>

ChatHub.cs

using System;
using System.Web;
using Microsoft.AspNet.SignalR;
using WebMatrix.Data;
using WebMatrix.WebData;

namespace SignalRChat
{
    public class ChatHub : Hub
    {
        public void Send(string message)
        {
            // Call the broadcastMessage method to update clients.
            var db = Database.Open("GamersInvest");
            string name = db.QueryValue("SELECT UserName FROM Users WHERE UserId = @0", WebSecurity.CurrentUserId);
            Clients.All.broadcastMessage(name, message);
        }
    }
}

Startup.cs

using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalRChat.Startup))]
namespace SignalRChat
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Any connection or hub wire up and configuration should go here
            app.MapSignalR();
        }
    }
}

Solution

  • If you're using ASP.NET Identity, you can use User.Identity.GetUserName() in your view to get the current logged in user's name. If you're using Forms Authentication, use User.Identity.Name for the user name. You can pull these into your JavaScript with Razor:

    For example, replace

    // Get the user name and store it to prepend to messages.    
    $('#displayname').val(prompt('Enter your name:', ''));
    

    with something like

    // Get the user name and store it to prepend to messages.
    $('#displayname').val("@HttpContext.Current.User.Identity.Name");
    

    Be sure to put in the right code for whichever identity system you're using.