发布到 IIS 服务器时未调用 OnDisconnected 在 Visual Studio 中工作正常
OnDisconnected not called when published to IIS server works fine in Visual Studio
如果之前已经问过,请原谅我。我环顾四周,但我遇到的任何已回答问题都没有影响我的情况。
我正在使用 SignalR 2.2.0
设置:我有一个 WebAPI 2 网络应用程序(简称为 API),它包含我的名为 ChatHub 的集线器。我有一个 MVC 站点 (MVC),它在 API 站点上调用我的集线器。
这两个站点都在同一台服务器上,只是端口不同。我使用的是 VS 2013,当我在本地测试时,我的本地系统也使用相同的端口...而且 url 到 API 站点是从 Web 配置加载的,这对于 Release 和 Debug 是不同的和本地(所以 url 是正确的,服务器上的端口很好......真正的错误是 OnDisconnected 没有被解雇)
经过大量的试错和搜索,我终于搞定了一个测试应用程序。一切都很完美。然后我不得不修改我的集线器以适应商业模式。 IE 获取用户和消息的内存列表并将它们记录在数据库中(除其他外)。 运行 在本地时一切正常,但是一旦站点发布到服务器上的 IIS ....永远不会调用 OnDisconnected。在测试应用程序/本地 运行 时,这几乎立即被大多数浏览器击中。但即使等待 15 分钟以上,该方法仍未触发。
这是我的中心:(为清楚起见简称)
/// <summary>
/// Chat Hub Class
/// </summary>
public class ChatHubAsync : Hub
{
#region Data Members
IDemographicsProvider DemographicsProvider { get; set;}
IChatRepository Repo { get; set; }
#endregion
#region CTOR
/// <summary>
/// Unity Constructor
/// </summary>
[InjectionConstructor]
public ChatHubAsync()
: this(new ChatRepositoryEF(), DataProviders.Demographics)
{
}
/// <summary>
/// Constructor for Chat Hub
/// </summary>
/// <param name="Repository"></param>
/// <param name="Demographics"></param>
public ChatHubAsync(IChatRepository Repository, IDemographicsProvider Demographics)
{
Repo = Repository;
DemographicsProvider = Demographics;
}
#endregion
#region Methods
/// <summary>
/// On Connected method to call base class
/// </summary>
/// <returns></returns>
public override async Task OnConnected()
{
await base.OnConnected();
}
/// <summary>
/// Connect to Hub
/// </summary>
/// <returns>Void</returns>
public async Task Connect()
{
if (await Repo.GetUser(Context.ConnectionId) == null)
{
await RemoveDuplicates(getGuidFromQueryString("userID"), getGuidFromQueryString("groupID"));
var user = await CreateUser();
await Repo.Connect(user);
await Clients.Caller.onConnected(user);
}
}
/// <summary>
/// Add User To Group
/// </summary>
/// <returns></returns>
public async Task AddToGroup()
{
Guid id = getGroupFromQueryString();
if (id != Guid.Empty)
{
string groupID = id.ToString();
var user = await Repo.GetUser(Context.ConnectionId);
try
{
if(user == null)
{
await Connect();
user = await Repo.GetUser(Context.ConnectionId);
}
await Groups.Add(Context.ConnectionId, groupID);
var users = await Repo.OnlineUsers(id);
var messages = await Repo.RetrieveMessages(id, 20);
var status = await Repo.AddOnlineUserToGroup(Context.ConnectionId, id);
await Clients.Caller.onGroupJoined(user, users, messages, status);
Clients.Group(groupID, Context.ConnectionId).onNewUserConnected(user);
}
catch(Exception E)
{
Console.WriteLine(E.Message);
}
}
}
/// .....More Methods that are irrelevant....
/// <summary>
/// Disconnect from Hub
/// </summary>
/// <param name="stopCalled"></param>
/// <returns></returns>
public override async Task OnDisconnected(bool stopCalled)
{
try
{
var item = await Repo.GetUser(Context.ConnectionId);
if (item != null)
{
if (item.GroupID != null && item.GroupID != Guid.Empty)
{
var id = item.GroupID.ToString();
Repo.Disconnect(Context.ConnectionId);
Clients.OthersInGroup(id).onUserDisconnected(Context.ConnectionId, item.UserName);
Groups.Remove(Context.ConnectionId, id);
}
}
}
catch (Exception E)
{
Console.WriteLine(E.Message);
}
await base.OnDisconnected(stopCalled);
}
#endregion
#region private Messages
private async Task<IOnlineUser> CreateUser()
{
///Code removed
}
private Guid getGroupFromQueryString()
{
return getGuidFromQueryString("groupID");
}
private Guid getGuidFromQueryString(string name)
{
Guid id;
try
{
var item = getItemFromQueryString(name);
if (Guid.TryParse(item, out id))
{
return id;
}
throw new Exception("Not a Valid Guid");
}
catch(Exception E)
{
Console.WriteLine(E.Message);
return Guid.Empty;
}
}
private async Task RemoveDuplicates(Guid User, Guid Group)
{
///Code removed
}
#endregion
}
更新:
我不知道为什么,但是一旦我删除了对数据库的调用(对数据库的所有调用)并返回到内存列表中,断开连接时又开始被调用。
使用直接 sql 或 EntityFramework 添加回对数据库的任何调用,并且 OnDisconnected 停止被调用。
知道为什么添加数据库调用会导致 onDisconnected 停止被调用吗?
以防其他人遇到此问题。问题是由于应用程序没有模拟正确的用户引起的....它在 visual studio 中运行良好,因为当模拟无法使用提供的用户时,它使用了我。在 VS 之外,它没有该选项,并尝试使用无法登录的机器帐户。这是通过在应用程序池中添加模拟而不是在 Web 配置中使用它来解决的。我在项目的早期使用异步调用时遇到了这个问题,但我认为我已经通过对 Web 配置进行一些更改来解决这些问题。我处理了我进行的所有异步调用,但它仍然在几个 select 区域失败,导致 OnDisconnect 无法在服务器上触发。
如果之前已经问过,请原谅我。我环顾四周,但我遇到的任何已回答问题都没有影响我的情况。
我正在使用 SignalR 2.2.0 设置:我有一个 WebAPI 2 网络应用程序(简称为 API),它包含我的名为 ChatHub 的集线器。我有一个 MVC 站点 (MVC),它在 API 站点上调用我的集线器。
这两个站点都在同一台服务器上,只是端口不同。我使用的是 VS 2013,当我在本地测试时,我的本地系统也使用相同的端口...而且 url 到 API 站点是从 Web 配置加载的,这对于 Release 和 Debug 是不同的和本地(所以 url 是正确的,服务器上的端口很好......真正的错误是 OnDisconnected 没有被解雇)
经过大量的试错和搜索,我终于搞定了一个测试应用程序。一切都很完美。然后我不得不修改我的集线器以适应商业模式。 IE 获取用户和消息的内存列表并将它们记录在数据库中(除其他外)。 运行 在本地时一切正常,但是一旦站点发布到服务器上的 IIS ....永远不会调用 OnDisconnected。在测试应用程序/本地 运行 时,这几乎立即被大多数浏览器击中。但即使等待 15 分钟以上,该方法仍未触发。
这是我的中心:(为清楚起见简称)
/// <summary>
/// Chat Hub Class
/// </summary>
public class ChatHubAsync : Hub
{
#region Data Members
IDemographicsProvider DemographicsProvider { get; set;}
IChatRepository Repo { get; set; }
#endregion
#region CTOR
/// <summary>
/// Unity Constructor
/// </summary>
[InjectionConstructor]
public ChatHubAsync()
: this(new ChatRepositoryEF(), DataProviders.Demographics)
{
}
/// <summary>
/// Constructor for Chat Hub
/// </summary>
/// <param name="Repository"></param>
/// <param name="Demographics"></param>
public ChatHubAsync(IChatRepository Repository, IDemographicsProvider Demographics)
{
Repo = Repository;
DemographicsProvider = Demographics;
}
#endregion
#region Methods
/// <summary>
/// On Connected method to call base class
/// </summary>
/// <returns></returns>
public override async Task OnConnected()
{
await base.OnConnected();
}
/// <summary>
/// Connect to Hub
/// </summary>
/// <returns>Void</returns>
public async Task Connect()
{
if (await Repo.GetUser(Context.ConnectionId) == null)
{
await RemoveDuplicates(getGuidFromQueryString("userID"), getGuidFromQueryString("groupID"));
var user = await CreateUser();
await Repo.Connect(user);
await Clients.Caller.onConnected(user);
}
}
/// <summary>
/// Add User To Group
/// </summary>
/// <returns></returns>
public async Task AddToGroup()
{
Guid id = getGroupFromQueryString();
if (id != Guid.Empty)
{
string groupID = id.ToString();
var user = await Repo.GetUser(Context.ConnectionId);
try
{
if(user == null)
{
await Connect();
user = await Repo.GetUser(Context.ConnectionId);
}
await Groups.Add(Context.ConnectionId, groupID);
var users = await Repo.OnlineUsers(id);
var messages = await Repo.RetrieveMessages(id, 20);
var status = await Repo.AddOnlineUserToGroup(Context.ConnectionId, id);
await Clients.Caller.onGroupJoined(user, users, messages, status);
Clients.Group(groupID, Context.ConnectionId).onNewUserConnected(user);
}
catch(Exception E)
{
Console.WriteLine(E.Message);
}
}
}
/// .....More Methods that are irrelevant....
/// <summary>
/// Disconnect from Hub
/// </summary>
/// <param name="stopCalled"></param>
/// <returns></returns>
public override async Task OnDisconnected(bool stopCalled)
{
try
{
var item = await Repo.GetUser(Context.ConnectionId);
if (item != null)
{
if (item.GroupID != null && item.GroupID != Guid.Empty)
{
var id = item.GroupID.ToString();
Repo.Disconnect(Context.ConnectionId);
Clients.OthersInGroup(id).onUserDisconnected(Context.ConnectionId, item.UserName);
Groups.Remove(Context.ConnectionId, id);
}
}
}
catch (Exception E)
{
Console.WriteLine(E.Message);
}
await base.OnDisconnected(stopCalled);
}
#endregion
#region private Messages
private async Task<IOnlineUser> CreateUser()
{
///Code removed
}
private Guid getGroupFromQueryString()
{
return getGuidFromQueryString("groupID");
}
private Guid getGuidFromQueryString(string name)
{
Guid id;
try
{
var item = getItemFromQueryString(name);
if (Guid.TryParse(item, out id))
{
return id;
}
throw new Exception("Not a Valid Guid");
}
catch(Exception E)
{
Console.WriteLine(E.Message);
return Guid.Empty;
}
}
private async Task RemoveDuplicates(Guid User, Guid Group)
{
///Code removed
}
#endregion
}
更新:
我不知道为什么,但是一旦我删除了对数据库的调用(对数据库的所有调用)并返回到内存列表中,断开连接时又开始被调用。
使用直接 sql 或 EntityFramework 添加回对数据库的任何调用,并且 OnDisconnected 停止被调用。
知道为什么添加数据库调用会导致 onDisconnected 停止被调用吗?
以防其他人遇到此问题。问题是由于应用程序没有模拟正确的用户引起的....它在 visual studio 中运行良好,因为当模拟无法使用提供的用户时,它使用了我。在 VS 之外,它没有该选项,并尝试使用无法登录的机器帐户。这是通过在应用程序池中添加模拟而不是在 Web 配置中使用它来解决的。我在项目的早期使用异步调用时遇到了这个问题,但我认为我已经通过对 Web 配置进行一些更改来解决这些问题。我处理了我进行的所有异步调用,但它仍然在几个 select 区域失败,导致 OnDisconnect 无法在服务器上触发。