我正在为我的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
,但没有。
以下是网络活动:
的数据
注意,negotiate
、start
和send
方法会立即给予200个HTTP状态,但connect
方法永远不会完成。
我试过在JS中添加订阅到集线器来强制连接,但没有工作。
1条答案
按热度按时间pnwntuvh1#
我在这里犯了一个新手错误。如果我只在Azure中启用Web套接字,代码就可以正常工作。此Web应用部署到Azure应用服务,由于SignalR使用Web套接字,因此必须打开它们,但Azure默认情况下禁用它们。只需登录Azure门户,转到您的应用服务>配置>常规设置,然后将Web套接字切换为“打开”。
**注意:**我在
ChatHub.cs
文件中生成了一个服务器端错误,但我无法在错误日志中捕获该错误,因为SignalR是通过Web套接字而不是HTTP运行的。要检测该错误,您应该在Azure门户中运行.NET Profiler跟踪。要到达该位置,请单击您的应用服务>诊断和解决问题>诊断工具>收集.NET Profiler跟踪。启动跟踪,然后在收集跟踪时通过触发对SignalR的调用来重现问题。这很重要,否则您将无法收集请求以及由此产生的任何缓慢、故障或异常。因此,如果SignalR方法没有在客户端触发,并且您认为存在服务器端错误,则进行调试的最佳途径是运行.NET分析器跟踪。