Shinance
Shinance

Reputation: 161

How to implement 'Who is typing' feature via SignalR?

Basically I am implementing a SignalR chat in my website. I can already send messages to all connected users and now I hope to add the "who is typing" feature. I'm trying to add it in the $('#message').keypress function and it works but now I can't send messages to users.

What did I do wrong?

After remove $('#message').keypress can send message

Didn't remove $('#message').keypress cannot send message

enter image description here

My html {

<input type="text" id="message" />
<input type="button" id="sendmessage" value="Send" class="btn btn-default" />
<input type="hidden" id="displayname" />
<label id="isTyping" />
<ul id="discussion"></ul>

}

Below is the script:

<!--SignalR script to update the chat page and send messages.-->
<script type="text/javascript">
    $(function () {
        // Reference the auto-generated proxy for the hub.
        var chat = $.connection.chatHub;
        // Create a function that the hub can call back to display messages.

        chat.client.broadcastMessage = function (name, message) {
            $('#discussion').append('<li><strong>' + name
                + '</strong>:&nbsp;&nbsp;' + message + '</li>');
        };

        chat.client.sayWhoIsTyping = function (name) {
            $('#isTyping').html('<em>' + name + ' is typing...</em>');
            setTimeout(function () {
                $('#isTyping').html('&nbsp;');
            }, 5000);
        };

        // 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 () {
                var encodedName = $('<div />').text($('#displayname').val()).html();
                var encodedMsg = $('<div />').text($('#message').val()).html();
                chat.server.sendPublic(encodedName, encodedMsg);
                $('#message').val('').focus();
            });

            $('#message').keypress(function (e) {
                if (e.which == 13) {
                    var encodedName = $('<div />').text($('#displayname').val()).html();
                    var encodedMsg = $('<div />').text($('#message').val()).html();
                    chat.server.sendPublic(encodedName, encodedMsg);
                    $('#message').val('').focus();
                } else {
                    var encodedName = $('<div />').text($('#displayname').val()).html();
                    chat.server.isTyping(encodedName);
                }
            });
        });



    // This optional function html-encodes messages for display in the page.
    function htmlEncode(value) {
        var encodedValue = $('<div />').text(value).html();
        return encodedValue;
    }

Below is my Hub code:

    public void SendPublic(string name, string message)
    {
        // Call the addNewMessageToPage method to update clients
        Clients.All.broadcastMessage(name, message);
    }

    public void IsTyping(string name)
    {
        SayWhoIsTyping(name);
    }

    public void SayWhoIsTyping(string name)
    {
        IHubContext context = GlobalHost.ConnectionManager.GetHubContext<ChatHub>();
        context.Clients.All.sayWhoIsTyping(name);
    }

Upvotes: 10

Views: 5120

Answers (2)

Sudhir Panda
Sudhir Panda

Reputation: 784

in the hub class Server Side

public void UserTyping(groupName)
{
    var userName = "Get current user's name";
    //client method here
    Clients.OthersInGroup(groupName).OtherUserIsTyping(userName);
}

Client Side

<textbox id="message"></textbox>
<span id="userTyping"></span>

var keyPressCount = 0;

$("#message").on("keypress", function () {
    if (e.which == 13) {
       $('#sendmessage').trigger('click');
    } 
    else {
       // Don't want to call the server on every keypress
       if (keyPressCount++ % 10 == 0) {
        chatHub.server.userTyping("myChatGroup");
       }
    }
});

chatHub.client.OtherUserIsTyping = function (userName) {
    $("#userTyping").html(userName + " is typing...");
};

Upvotes: 2

Lucaci Andrei
Lucaci Andrei

Reputation: 407

On your server you'll have to have two methonds in your ChatHub with the name:

public void IsTyping (string html) 
{
    // do stuff with the html
    SayWhoIsTyping(html); //call the function to send the html to the other clients
}

public void SayWhoIsTyping (string html)
{
    IHubContext context = GlobalHost.ConnectionManager.GetHubContext<ChatHub>();
    context.Clients.All.sayWhoIsTyping (html);
}

How does this process work?

You catch the event that one of your clients is typing, that is with the keypress function from javascript. You then call a function from the server with your desired html, containing the name and other information. The server receives the information, process it, and then call a function from the client which does the trick of displaying who's typing.

In your case, your IsTyping method from server will handle the information which is coming from the client, and the SayWhoIsTyping method from the server will be calling the client to handle it the required information.

Edit to your comment:

I would advise modifying the function from javascript like this:

chat.client.sayWhoIsTyping = function (name) {
    $('#isTyping').html('<em>' + name + ' is typing...</em>');
    setTimeout(function () {
        $('#isTyping').html('&nbsp;');
    }, 5000);
};

$('#message').keypress(function(e) {
    if (e.which == 13) {
        $('#sendmessage').trigger('click');
    } else {
        var encodedName = $('<div />').text($('#displayname').val()).html();
        chat.server.isTyping(encodedName);
    }
});

and to remove the $(document).keypress function.

Upvotes: 10

Related Questions