草庐IT

c# - SignalR C# MVC 将匿名用户映射到客户端 ID

coder 2024-05-25 原文

问题:如何管理匿名用户,以便当 Hub 发出响应时,单个浏览器中的多个选项卡全部更新?

场景如下:

我想将 SignalR 集成到一个项目中,以便匿名用户可以与运算符(operator)实时聊天。显然,已通过 iIdentity 进行身份验证的用户是通过 Client.User(username) 命令映射的。但是目前说一个匿名用户正在浏览 site.com/tools 和 site.com/notTools 我不能只用一个 connectionID 向所有选项卡发送消息。只有一个选项卡收集响应。

我曾尝试使用 IWC 补丁,但该工具无法将聊天信息保存到数据库中,而且我认为通过 ajax 传递变量并不是读取/写入数据库的安全方式。

我还查看了以下内容:Managing SignalR connections for Anonymous user

然而,创建这样的基础并使用 session 似乎不如 Owin 安全。

我想通过在用户每次连接时创建一个虚假帐户并在他们断开连接时删除它来使用 client.user()。但我不想用垃圾帐户填充我的 aspnetusers 数据库上下文,这似乎是不必要的。

是否可以使用 UserHandler.ConnectedIds.Add(Context.ConnectionId); 来映射假用户名?我不知所措。

使用 iUserId 提供程序有意义吗?

public interface IUserIdProvider
{
    string GetUserId(IRequest request);
}

然后创建一个数据库来存储 IP 地址到连接 ID 和单个用户名?

数据库:

用户:通过 FK 连接 ID

|userid|username|IP       |connectionIDs|
|   1  | user1  |127.0.0.1|  1          |
|   2  | user2  |127.0.0.2|  2          |

connectionIDs:

|connectionID|SignalRID|connectionIDs|
|      1     | xx.x.x.x|     1       |
|      2     | xx.xxx.x|     2       |
|      3     | xx.xxxxx|     2       |
|      4     | xxxxx.xx|     2       |

然后可能围绕连接编写逻辑?

public override Task OnConnected()
    {
     if(Context.Identity.UserName != null){
      //add a connection based on the currently logged in user. 
     }
    else{
     ///save new user to database?
     } 
  }

但问题仍然存在,当在 websocket 上发送命令时,我将如何处理多个选项卡?

更新 明确地说,我的意图是创建一个实时聊天/支持工具,允许在浏览器中始终进行匿名访问。

客户想要类似 http://www.livechatinc.com 的东西

我已经创建了一个 javascript 插件,无论它在哪个域上,它都可以从集线器发送和接收。 (我的客户有多个站点)拼图中缺少的部分是最简单的,管理匿名用户以允许多选项卡对话。

最佳答案

我不遵循虚假用户帐户的想法(不知道它是否有效),但会开发一个替代方案。

可以通过所有浏览器选项卡共享的 ChatSessionId cookie 并创建以此 ChatSessionId 命名的组来实现该目标。

我从 asp.net/signalr 学习了基本的聊天教程并添加了允许同一用户从多个选项卡聊天的功能。

1) 在“聊天”操作中分配聊天 session ID 以识别用户,因为我们没有用户凭据:

    public ActionResult Chat()
    {
        ChatSessionHelper.SetChatSessionCookie();
        return View();
    }

2) 进入聊天页面时订阅聊天 session

客户端

    $.connection.hub.start()
        .then(function(){chat.server.joinChatSession();})
        .done(function() {
           ...

服务器端(集线器)

public Task JoinChatSession()
{
    //get user SessionId to allow use multiple tabs
    var sessionId = ChatSessionHelper.GetChatSessionId();
    if (string.IsNullOrEmpty(sessionId)) throw new InvalidOperationException("No chat session id");

    return Groups.Add(Context.ConnectionId, sessionId);
}

3) 向用户的聊天 session 广播消息

public void Send(string message)
{
    //get user chat session id
    var sessionId = ChatSessionHelper.GetChatSessionId();
    if (string.IsNullOrEmpty(sessionId)) throw new InvalidOperationException("No chat session id");

    //now message will appear in all tabs
    Clients.Group(sessionId).addNewMessageToPage(message);
}

最后,(简单的)ChatSessionHelper 类

public static class ChatSessionHelper
{
    public static void SetChatSessionCookie()
    {
        var context = HttpContext.Current;
        HttpCookie cookie = context.Request.Cookies.Get("Session") ?? new HttpCookie("Session", GenerateChatSessionId());

        context.Response.Cookies.Add(cookie);
    }

    public static string GetChatSessionId()
    {
        return HttpContext.Current.Request.Cookies.Get("Session")?.Value;
    }

    public static string GenerateChatSessionId()
    {
        return Guid.NewGuid().ToString();
    }
}

关于c# - SignalR C# MVC 将匿名用户映射到客户端 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34913972/

有关c# - SignalR C# MVC 将匿名用户映射到客户端 ID的更多相关文章

  1. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  2. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  3. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  4. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  5. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

  6. ruby - 在匿名 block 中产生 - 2

    我没有理解以下行为(另请参阅inthisSOthread):defdef_testputs'def_test.in'yieldifblock_given?puts'def_test.out'enddef_testdoputs'def_testok'endblock_test=procdo|&block|puts'block_test.in'block.callifblockputs'block_test.out'endblock_test.calldoputs'block_test'endproc_test=procdoputs'proc_test.in'yieldifblock_gi

  7. ruby - RVM "ERROR: Unable to checkout branch ."单用户 - 2

    我在新的Debian6VirtualBoxVM上安装RVM时遇到问题。我已经安装了所有需要的包并使用下载了安装脚本(curl-shttps://rvm.beginrescueend.com/install/rvm)>rvm,但以单个用户身份运行时bashrvm我收到以下错误消息:ERROR:Unabletocheckoutbranch.安装在这里停止,并且(据我所知)没有安装RVM的任何文件。如果我以root身份运行脚本(对于多用户安装),我会收到另一条消息:Successfullycheckedoutbranch''安装程序继续并指示成功,但未添加.rvm目录,甚至在修改我的.bas

  8. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  9. ruby - 在没有基准或时间的情况下用 Ruby 测量用户时间或系统时间 - 2

    因为我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序time的情况下测量用户时间或系统时间。使用Time类只显示挂钟时间,而不显示系统和用户时间,但是我正在寻找具有相同灵active的解决方案,例如time=TimeUtility.now#somecodeuser,system,real=TimeUtility.now-time原因是我有点不喜欢Benchmark,因为它不能只返回数字(编辑:我错了-它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX系统的time实用程序也应该可以解决我的问题,但我想知道是否已经在Ruby中实

  10. ruby - Rails -- :id attribute? 所需的数据库索引 - 2

    因此,当我遵循MichaelHartl的RubyonRails教程时,我注意到在用户表中,我们为:email属性添加了一个唯一索引,以提高find的效率方法,因此它不会逐行搜索。到目前为止,我们一直在根据情况使用find_by_email和find_by_id进行搜索。然而,我们从未为:id属性设置索引。:id是否自动索引,因为它在默认情况下是唯一的并且本质上是顺序的?或者情况并非如此,我应该为:id搜索添加索引吗? 最佳答案 大多数数据库(包括sqlite,这是RoR中的默认数据库)会自动索引主键,对于RailsMigration

随机推荐