【问题标题】:OnDisconnected not called when published to IIS server works fine in Visual Studio发布到 IIS 服务器时未调用 OnDisconnected 在 Visual Studio 中工作正常
【发布时间】:2015-03-05 22:53:14
【问题描述】:

如果以前有人问过这个问题,请原谅我。我环顾四周,但我遇到的任何已回答的问题都没有影响我的情况。

我正在使用 SignalR 2.2.0 设置:我有一个 WebAPI 2 Web 应用程序(简称为 API),它包含我的集线器 ChatHub。我有一个 MVC 站点 (MVC),它在 API 站点上调用我的中心。

这两个站点都在同一台服务器上,只是端口不同。我正在使用 VS 2013,当我在本地进行测试时,我的本地系统也使用相同的端口……API 站点的 url 也是从 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
   }

更新:

我不知道为什么,但是一旦我删除了对数据库的调用(ALL CALLS TO THE DATABASE)并返回到内存列表中,On Disconnected 又开始被调用。

使用直接 sql 或 EntityFramework 添加回对数据库的任何调用,并且 OnDisconnected 停止被调用。

任何想法为什么添加数据库调用会导致 onDisconnected 停止被调用?

【问题讨论】:

    标签: iis model-view-controller signalr asp.net-web-api signalr-hub


    【解决方案1】:

    以防其他人遇到此问题。问题是由于应用程序没有模拟正确的用户造成的......它在 Visual Studio 中运行良好,因为当模拟未能使用提供的用户时,它使用了我。在 VS 之外,它没有该选项并尝试使用无法登录的机器帐户。通过在应用程序池中添加模拟而不是在 Web 配置中使用它来解决此问题。我在项目早期使用异步调用时遇到了这个问题,但我认为我已经通过对 Web 配置的一些更改来解决这些问题。我处理了我正在进行的所有异步调用,但在一些选定的区域仍然失败,导致 OnDisconnect 无法在服务器上触发。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-09
      • 2021-05-25
      • 1970-01-01
      • 2014-11-28
      • 1970-01-01
      • 2023-04-01
      • 2022-01-16
      • 2017-03-06
      相关资源
      最近更新 更多