0

I used this code so far but i don't receive properly ordered messages output so can any one help me for proper output.

ChatHub Code :

public class ChatHub : Hub
{
    static List<UserDetails> ConnectedUsers = new List<UserDetails>();
    static List<MessageDetails> CurrentMessage = new List<MessageDetails>();

    static List<TestProject1.Models.MessageDetails> CurrentMessage1 = new List<TestProject1.Models.MessageDetails>();

    private TestContext db = new TestContext();

    public void Connect(string userName)
    {
        var id = Context.ConnectionId;
        var data = db.MessageDetails.ToList();
        foreach (var item in data)
        {

            ConnectedUsers.Add(new UserDetails { ConnectionId = id, UserName = item.UserName });

            CurrentMessage1.Add(new TestProject1.Models.MessageDetails { UserName = item.UserName, Message = item.Message });
        }
        Clients.Caller.onConnected(id, userName, ConnectedUsers, CurrentMessage1);

        Clients.AllExcept(id).onNewUserConnected(id, userName); 
    }

    public void Send(string name, string message, string connection)
    {
        AddMessageinCache(name, message);
        db.MessageDetails.Add(new TestProject1.Models.MessageDetails { UserName = name, Message = message });
        db.SaveChanges();
        Clients.All.addNewMessageToPage(name, message, connection);
    }

    private void AddMessageinCache(string userName, string message)
    {   
        CurrentMessage.Add(new MessageDetails { UserName = userName, Message = message });

        if (CurrentMessage.Count > 100)
            CurrentMessage.RemoveAt(0);
    }
}

I also include details of my html code here And Code of CSHTML:

<div id="page-content">
    <div id='wrap'>
        <div id="page-heading">
            <ol class="breadcrumb">
                <li><a href="@Url.Action("Index")">Dashboard</a></li>
                <li>Chat Room</li>
            </ol>    
            <h1>Chat Room</h1>    
        </div>    
        <div class="container">
            <div class="col-md-12">
                <div class="panel panel-inverse">
                    <div class="panel-heading">
                        <h4>Chat Room</h4>
                        <div class="options">
                            <a href="javascript:;"><i class="fa fa-cog"></i></a>
                            <a href="javascript:;"><i class="fa fa-refresh"></i></a>
                        </div>
                    </div>
                    <div class="panel-body">
                        <div class="row">
                            <div class="col-md-8">
                                <div class="panel-chat well" id="chat">                                      
                                </div>
                                <form class="form-inline" action="#">
                                    <div class="input-group">
                                        <input type="text" placeholder="Enter your message here" id="message" class="form-control">
                                        <span class="input-group-btn">
                                            <button type="button" id="sendmessage" class="btn btn-primary"><i class="fa fa-comments-o"></i></button>
                                        </span>
                                    </div>
                                </form>
                                <input type="hidden" id="displayname" />
                                <input type="hidden" id="connection" />
                            </div>
                         </div>    
                    </div>
                </div>
            </div>
        </div>    
     </div> <!--wrap -->
</div> <!-- page-content -->       

@section Scripts
{
@Scripts.Render("~/bundles/jquery")
<script>
    jQuery(function () {
        $.connection.hub.url = 'http://localhost:34063//signalr';
        // Reference the auto-generated proxy for the hub.

        var chat = $.connection.chatHub;

        chat.client.onConnected = function (id, userName, allUsers, messages) {
            for (i = 0; i < messages.length; i++) {
                AddMessage(messages[i].UserName, messages[i].Message);
            }
        }

        // Create a function that the hub can call back to display messages.
        chat.client.addNewMessageToPage = function (name, message, connectionid) {
            // Add the message to the page.
            $('#chat').append('<div class="chat-message me"><div class="chat-contact"><img src="/Content/assets/demo/avatar/avatar.png" alt=""></div><div class="chat-text">' + htmlEncode(name)
                + ': ' + htmlEncode(message) + '</div></div>');
        };
        // Get the user name and store it to prepend to messages.
        $('#displayname').val('@Session["User"].ToString()');
        $('#connection').val(@Session["UserID"]);
        var name = $('#displayname').val();

        // Set initial focus to message input box.
        $('#message').focus();
        // Start the connection.
        var i = 0;
        $.connection.hub.start().done(function () {
            if (name.length > 0) {
                if (i == 1) {
                    chat.server.connect(name);
                }
            }

            $('#sendmessage').click(function () {
                chat.server.send($('#displayname').val(), $('#message').val(), $('#connection').val());
                $('#message').val('').focus();
            });
        });

        i = i + 1;
        $.connection.hub.disconnected(function () {
            alert('Disconnected');
        });
    });   

    // This optional function html-encodes messages for display in the page.
    function AddMessage(userName, message) {
        $('#chat').append('<div class="chat-message me"><div class="chat-contact"><img src="/Content/assets/demo/avatar/avatar.png" alt=""></div><div class="chat-text">' + userName + ': ' + message + '</div></div>');
    }

    function htmlEncode(value) {
        var encodedValue = $('<div />').text(value).html();
        return encodedValue;
    }
</script>
}

output is showing all messages but not showing in a sorted order and repeating messages on loading of a page. I want to remove it too.

TheVillageIdiot
  • 40,053
  • 20
  • 133
  • 188
Deepak
  • 1
  • 1

1 Answers1

0

Why you don't add DateTime stamps to messages. In your MessageDetails class add a property:

public DateTime ReceivedOn{get;set;}

Modify code that runs on receiving message:

private void AddMessageinCache(string userName, string message)
{   
    CurrentMessage.Add(new MessageDetails { UserName = userName, Message = message, ReceivedOn=DateTime.Now });

    if (CurrentMessage.Count > 100)
        CurrentMessage.RemoveAt(0);
}

On client side, you will need to sort messages on ReceivedOn property:

chat.client.onConnected = function (id, userName, allUsers, messages) {
    $.sort(messages,function(a,b){
           return a.ReceivedOn > b.ReceivedOn;
    });

    for (i = 0; i < messages.length; i++) {
        AddMessage(messages[i].UserName, messages[i].Message);
    }
}

Consult this question on sorting in jQuery.

EDIT:- On a side note, if only already received messages are a problem, then why don't fetch those sorted from database itself?

Community
  • 1
  • 1
TheVillageIdiot
  • 40,053
  • 20
  • 133
  • 188