SignalR and MVC 5 partial views

846 views Asked by At

Hey guys I have the following issue with Asp SignalR. I want to have a chat with Admins and Users. I have 1 View with two divs (! for the Admin and 1 for the users), which I show or hide by checking the user. So far so good, everything works ! Both the admins and users get the necessary divs and can exchange messages - red div admin, blue div user.. Take a look at the code and I'll explain where I get a problem.

<div class="Admin" id="divMessageAdmin" style="background-color:red;">
    <div class="welcome"></div><br />
    <div id="divWaitingUser"></div><br />
    <input id="txtMessage" type="text" />
    <input id="btnSendMessage" type="button" value="Send" />
    <div id="divAdminMessage"></div>
</div>

<div class="User" id="divMessageUser" style="background-color:blue;">
    <div class="welcome"></div><br />
    <input id="txtUserMessage" type="text" />
    <input id="btnSendUserMessage" type="button" value="Send" />
    <div id="divUserMessage"></div>
</div>

    <input id="hUserId" type="hidden" />
    <input id="hId" type="hidden" />
    <input id="hUserName" type="hidden" />
    <input id="hGroup" type="hidden" />

@section scripts {
    <script src="~/Scripts/jquery-1.10.2.min.js"></script>
    <script src="~/Scripts/jquery.signalR-2.2.1.min.js"></script>
    <script src="~/signalr/hubs" type="text/javascript"></script>

    <script>
        $(function () {
           var objHub = $.connection.chatHub;
           loadClientMethods(objHub);
           $.connection.hub.start().done(function () {
               loadEvents(objHub);
           });
       });

       function loadEvents(objHub) {

           var name = '@HttpContext.Current.User.Identity.Name';
           objHub.server.connect(name);
           //alert(name);

           $('#btnSendMessage').click(function () {
               var msg = $("#txtMessage").val();
               if (msg.length > 0) {
                   var username = $('#hUserName').val();
                   document.getElementById('txtMessage').value = "";
                   // <<<<<-- ***** Return to Server [  SendMessageToGroup  ] *****
                   objHub.server.sendMessageToGroup(username, msg);
               }
           });

           $('#btnSendUserMessage').click(function () {
              // alert("wrks");
               var msg = $("#txtUserMessage").val();
               if (msg.length > 0) {
                   var username = $('#hUserName').val();
                   document.getElementById('txtUserMessage').value = "";
                   // <<<<<-- ***** Return to Server [  SendMessageToGroup  ] *****
                   objHub.server.sendMessageToGroup(username, msg);
               }
           });

           $("#txtMessage").keypress(function (e) {
               if (e.which == 13) {
                   $('#btnSendMessage').click();
               }
           });
       }

        function loadClientMethods(objHub) {

           objHub.client.getMessagesAdmin = function (userName, message) {
                   $(".txtMessage").val('');
                   $('#divAdminMessage').append('<div><p>' + userName + ': ' + message + '</p></div>');
                   var height = $('#divAdminMessage')[0].scrollHeight;
                   $('#divAdminMessage').scrollTop(height);
           }

           objHub.client.getMessagesUser = function (userName, message) {
               $("#txtMessage").val('');
               $('#divUserMessage').append('<div><p>' + userName + ': ' + message + '</p></div>');
               var height = $('#divUserMessage')[0].scrollHeight;
               $('#divUserMessage').scrollTop(height);
           }

           objHub.client.onConnected = function (id, userName, UserID, userGroup, flag) {
               alert(flag);
               var strWelcome = 'Welcome' + +userName;
               $('.welcome').append('<div><p>Welcome:' + userName + '</p></div>');
               $('#hId').val(id);
               $('#hUserId').val(UserID);
               $('#hUserName').val(userName);
               $('#hGroup').val(userGroup);
               if ( flag == "1") {
                   $("#divMessageUser").hide();
                   $("#divMessageAdmin").show();
               }
               else {
                   $("#divMessageUser").show();
                   $("#divMessageAdmin").hide();
               }
           }
       }
    </script>
}

The thing is, that I want these two divs to be in separated Partial Views. This is what I'm trying. At the beginning of my page I check if the user is authenticated, if it is I fire a [ChildActionOnly] action method in my ChatController:

<h2>Chat</h2>
@{
    if (!User.Identity.IsAuthenticated)
    {
        @Html.Partial("_UnauthenticatedUserForm");
    }
    else
    {
        Html.RenderAction("AuthenticatedUsersChat");
    }
}

and my action method in the controller

[ChildActionOnly]
public ActionResult AuthenticatedUsersChat()
{
    AppContext db = new AppContext();
    User user = db.Users.Single(usr => usr.Email == User.Identity.Name);
    int isAdmin = user.AdminCode;
    if (isAdmin == 0)
    {
        return PartialView("_UserChatPartial");
    }
    else
    {
        return PartialView("_AdminChatPartial");
    }
}

this works and the partial views are returning in the way I want. In both partial views I've moved the divs ONLY! Admin Partial:

<div class="Admin" id="divMessageAdmin" style="background-color:red;">
    <div class="welcome"></div><br />
    <div id="divWaitingUser"></div><br />
    <input id="txtMessage" type="text" />
    <input id="btnSendMessage" type="button" value="Send" />
    <div id="divAdminMessage"></div>
</div>

and UserPartial

<div class="User" id="divMessageUser" style="background-color:blue;">
    <div class="welcome"></div><br />
    <input id="txtUserMessage" type="text" />
    <input id="btnSendUserMessage" type="button" value="Send" />
    <div id="divUserMessage"></div>
</div>

BUT somehow then only the Administrator can see the messages. The user can send messages (admin receives it), but the user cannot see his or admins messages - result. I simply don't see any logic why only the user can't see the messages. Please if you have any ideas help me. Thanks in advance !

my method for the messages in the hub class

public void SendMessageToGroup(string userName, string message)
{
    if (UsersList.Count != 0)
    {
        var strg = (from s in UsersList where (s.Email == userName) select s).First();
        MessageList.Add(new MessageInfo { UserName = userName, Message = message, UserGroup = strg.UserGroup });
        string strgroup = strg.UserGroup;
        Clients.Group(strgroup).getMessagesAdmin(userName, message);
        Clients.Group(strgroup).getMessagesUser(userName, message);
    }
}
// End SendMessage

and the connection method in the hub

public void Connect(string userName)
{
        //if freeflag==0 ==> Busy
        //if freeflag==1 ==> Free

        //if tpflag==0 ==> User
        //if tpflag==1 ==> Admin

    var id = Context.ConnectionId;
    string userGroup = "";

    AppContext db = new AppContext();
    var userInfo = (from m in db.Users
                    where m.Email == HttpContext.Current.User.Identity.Name
                    select new { m.UserId, m.Email, m.AdminCode, m.FirstName, m.LastName }).FirstOrDefault();

    try
    {
        if ((int)userInfo.AdminCode == 0)
        {
            var strg = (from s in UsersList where (s.tpflag == "1") && (s.freeflag == "1") select s).First();
            userGroup = strg.UserGroup;
            strg.freeflag = "0";
            //now add USER to UsersList
            UsersList.Add(new User { ConnectionId = id, UserId = userInfo.UserId, Email = userName, UserGroup = userGroup, freeflag = "0", tpflag = "0", });
            var flag = (from s in UsersList where (s.Email == userName) select s.tpflag); 
            Groups.Add(Context.ConnectionId, userGroup);
            Clients.Caller.onConnected(id, userName, userInfo.UserId, userGroup, flag);
        }
        else
        {
            UsersList.Add(new User { ConnectionId = id, UserId = userInfo.UserId, Email = userName, UserGroup = userInfo.AdminCode.ToString(), freeflag = "1", tpflag = "1" });
            var flag = (from s in UsersList where (s.Email == userName) select s.tpflag); 
            Groups.Add(Context.ConnectionId, userInfo.AdminCode.ToString());
            Clients.Caller.onConnected(id, userName, userInfo.UserId, userInfo.AdminCode.ToString(), flag);
        }
    }
    catch
    {
        Clients.Caller.NoExistAdmin();
    }
}
1

There are 1 answers

2
Igor Lizunov On

Sounds like your "blue" user is not in the group strgroup which you're trying to send to. Set a breakpoint to this line in the SendMessageToGroup method and check it.

Also strange code in if ((int)userInfo.AdminCode == 0) why to get First from UsersList and then add to it again? May be exception here?