asp.net OnConnected函数不会在Azure应用服务上的SignalR中触发

ycggw6v2  于 2023-11-20  发布在  .NET
关注(0)|答案(1)|浏览(95)

我正在为我的Azure网站制作一个聊天应用程序,用ASP.NET Web Forms开发,使用SignalR。
为了简单起见,我将复制两个主要的C#文件。

ChatHub.cs

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

    public void Connect(string userName)
    {
        var id = Context.ConnectionId;
       
        if (ConnectedUsers.Count(x => x.ConnectionId == id) == 0)
        {
            string logintime = DateTime.Now.ToString();
            ConnectedUsers.Add(new Users { ConnectionId = id, UserName = userName, LoginTime = logintime });
            Clients.Caller.onConnected(id, userName, ConnectedUsers, CurrentMessage);
            Clients.AllExcept(id).onNewUserConnected(id, userName, logintime);
        }
    }

    public void SendMessageToAll(string userName, string message, string time)
    {
        AddMessageinCache(userName, message, time);
        Clients.All.messageReceived(userName, message, time);
    }

    private void AddMessageinCache(string userName, string message, string time)
    {
        CurrentMessage.Add(new Messages { UserName = userName, Message = message, Time = time });
        if (CurrentMessage.Count > 100)
            CurrentMessage.RemoveAt(0);
    }

    public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled)
    {
        var item = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);
        if (item != null)
        {
            ConnectedUsers.Remove(item);
            var id = Context.ConnectionId;
            Clients.All.onUserDisconnected(id, item.UserName);
        }
        return base.OnDisconnected(stopCalled);
    }
}

字符串

Chat.aspx(JavaScript)

$(function() {
    var chatHub = $.connection.chatHub;
    registerClientMethods(chatHub);
    $.connection.hub.start().done(function () {
        registerEvents(chatHub);
    });

    function registerEvents(chatHub) {
        var name = '<%= this.UserName %>';   
        if (name.length > 0) {
            chatHub.server.connect(name);
        }
    }

    function registerClientMethods(chatHub) {
        chatHub.client.onConnected = function (id, userName, allUsers, messages, times) {
            console.log("Connected");
        }
        
        chatHub.client.onNewUserConnected = function (id, name, loginDate) {
            console.log("User Connected");
        }

        chatHub.client.onUserDisconnected = function (id, userName) {
            console.log("User Disconnected");
        }

        chatHub.client.messageReceived = function (userName, message, time) {
            console.log("Message Received");
        }
    }
});


在必要的时候,除了messageReceived之外,集线器的客户端方法都不会被触发,这一点从没有console.log()消息出现就可以看出。Connect()方法由下面这行调用:

chatHub.server.connect(name);


在服务器端,OnConnected()Connect()中被调用:

Clients.Caller.onConnected(id, userName, ConnectedUsers, CurrentMessage);


因此,它应该触发JavaScript函数chatHub.client.onConnected,但没有。
以下是网络活动:


的数据
注意,negotiatestartsend方法会立即给予200个HTTP状态,但connect方法永远不会完成。
我试过在JS中添加订阅到集线器来强制连接,但没有工作。

pnwntuvh

pnwntuvh1#

我在这里犯了一个新手错误。如果我只在Azure中启用Web套接字,代码就可以正常工作。此Web应用部署到Azure应用服务,由于SignalR使用Web套接字,因此必须打开它们,但Azure默认情况下禁用它们。只需登录Azure门户,转到您的应用服务>配置>常规设置,然后将Web套接字切换为“打开”。

**注意:**我在ChatHub.cs文件中生成了一个服务器端错误,但我无法在错误日志中捕获该错误,因为SignalR是通过Web套接字而不是HTTP运行的。要检测该错误,您应该在Azure门户中运行.NET Profiler跟踪。要到达该位置,请单击您的应用服务>诊断和解决问题>诊断工具>收集.NET Profiler跟踪。启动跟踪,然后在收集跟踪时通过触发对SignalR的调用来重现问题。这很重要,否则您将无法收集请求以及由此产生的任何缓慢、故障或异常。

因此,如果SignalR方法没有在客户端触发,并且您认为存在服务器端错误,则进行调试的最佳途径是运行.NET分析器跟踪。

相关问题