使用signalr hub进行实时聊天会产生错误

时间:2017-05-06 19:19:39

标签: c# asp.net asp.net-mvc entity-framework signalr

我正在开发一个应用程序,我使用SignalR和MVC5建立了一个实时聊天。我正在使用First Code EF。如果我只是使用发送,接收和保存聊天到数据库(聊天表),这个聊天工作正常,但如果我添加onconnect方法从数据库检索聊天,它甚至停止工作发送和检索将停止无论是。每当我评论onconnect方法时,其他方法都可以正常工作。 (onconnect方法正常,但突然停止工作)。我尝试了很多搜索解决方案并继续尝试一周,但仍然遇到这个问题。

调试此问题时,错误是:

  

XML解析错误:找不到根元素位置:   http://localhost:49430/signalr/abort?transport=serverSentEvents&clientProtocol=1.5&

当我点击此错误以获取更多详细信息时,它会给出:

  

为属性'AspNetUsers'检测到类型的自引用循环   'System.Data.Entity.DynamicProxies.ApplicationUser_23AA294498688966C3E26561B78E32FEA355D79546483C6C3DD66A96A9AF5D33'。   路径'A [1] [0] .Posts [0]

我相信问题就在这里:

return Clients.Caller.connected(userName, allUsers, messages);

我把它改成了

return Clients.All.connected(userName, allUsers, messages);

但仍然无法正常工作,我们将不胜感激。

这是我的中心课程:

namespace myWall
{
    public class ChatHub : Hub
    {
        public override System.Threading.Tasks.Task OnConnected()
        {
            ApplicationDbContext db = new ApplicationDbContext();
            string userName = Context.User.Identity.Name;

            var allUsers = db.Users.ToList();
            var messages = db.Chats.ToList();

            return Clients.Caller.connected(userName, allUsers, messages);
        }

        public void SendMessageToAll(string UserName, string message)
        {
            ApplicationDbContext dc = new ApplicationDbContext();
            UserName = Context.User.Identity.Name;

            AddAllMessageinCache(UserName, message);

            // Broad cast message
            Clients.All.NewMessage(UserName, message);
        }

        private void AddAllMessageinCache(string UserName, string message)
        {    
            var userId = Context.User.Identity.GetUserId();
            using (ApplicationDbContext dc = new ApplicationDbContext())
            {
                var messageDetail = new Chat
                {
                    UserId = userId,
                    userName = UserName,
                    Message = message
                };
                dc.Chats.Add(messageDetail);
                dc.SaveChanges();
            }
        }
    }

在我的HomeController中,我使用名为chat ActionResult的简单方法,并将此方法的视图添加到connect到集线器类。 这是我的聊天视图:(这只是不包含html表单的脚本代码,因为它只是简单的形式)

@section scripts {

    <script src="~/Scripts/jquery.signalR-2.2.1.js"></script>
    <script src="~/signalr/Hubs"></script>

    <script>
                $(function () {

                    var chat = $.connection.chatHub;



                    chat.client.connected = function (userName, allUsers, messages) {
                        for (i = 0; i < allUsers.length; i++) {
                            $("#results").append(allUsers[i].UserName + "</br>");

                        }

                        for (i = 0; i < 20; i++) {
                            $("#oldmsg").append(messages[i].userName + ": " + messages[i].Message + "</br>");
                        }
                        $("#oldmsg").append( "<font color= 'red' >" + "Welcome " + "<strong>" + userName + "</strong>" + " to the most fantastic real time chat" + "</font>" + "</br>");
                        $('#chat').scrollTop($('#chat')[0].scrollHeight);
                    };



                    chat.client.NewMessage = function (userName, msg) {
                        $('#Chats').append('<li><strong>' + htmlEncode(userName)
                            + '</strong>: ' + htmlEncode(msg) + '</li>');
                    };

                    registerClientMethods(chat)

                    $.connection.hub.start().done(function () {
                        registerEvents(chat)
                    });
                });




                function registerEvents(chat) {




                    $('#BtnSend').click(function () {
                        chat.server.sendMessageToAll($('#UserName').val(), $('#TxtMessage').val());
                        $('#TxtMessage').val('').focus();
                    });
                }

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


    </script>

这是我的聊天表:

[Table("Chat")]
public partial class Chat
{
    public int Id { get; set; }

    [StringLength(128)]
    public string UserId { get; set; }

    public int? WallId { get; set; }

    public DateTime? Time { get; set; }

    [Required]
    [StringLength(500)]
    public string Message { get; set; }

    [MaxLength(1)]
    public byte[] File { get; set; }

    public int? Code { get; set; }

    [Required]
    [StringLength(50)]
    public string userName { get; set; }

    [StringLength(256)]
    public string ConnectionId { get; set; }
}

1 个答案:

答案 0 :(得分:1)

您的覆盖应返回base.OnConnected。因此,请调用Client.Caller.connected,然后返回base.OnConnected

喜欢这个

public override System.Threading.Tasks.Task OnConnected()
    {
        ApplicationDbContext db = new ApplicationDbContext();
        string userName = Context.User.Identity.Name;

        var allUsers = db.Users.ToList();
        var messages = db.Chats.ToList();

        Clients.Caller.connected(userName, allUsers, messages);
        return base.OnConnected();
     }