ServiceStack:手动调用服务时恢复管道?

2024-03-31

作为后续这个问题 https://stackoverflow.com/questions/64560997/servicestack-messaging-api-can-it-make-a-broadcast,我想了解如何改进我对服务的手动调用。这比我想要的要长,但我觉得需要背景信息。

在执行 pub/sub(广播)时,不使用消息 API 中的正常顺序和流程,而是在收到 pub/sub 消息时使用 IRedisClient、IRedisSubscription 获得回调:

_subscription.OnMessage = (channel, msg) =>
{
    onMessageReceived(ParseJsonMsgToPoco(msg));
};

那个行动onMessageReceived然后,将依次调用普通的 .NET/C# 事件,如下所示:

protected override void OnMessageReceived(MyRequest request)
{
    OnMyEvent?.Invoke(this, new RequestEventArgs(request));
}

这可行,我收到了我的请求以及所有这些,但是,我希望将其简化为另一个流程,即消息传递 API 中的流程,这意味着请求找到了进入Service类实现,并且所有正常的样板文件和依赖项注入都像使用消息传递 API 一样发生。

因此,在我的事件处理程序中,我手动调用该服务:

private void Instance_OnMyEvent(object sender, RequestEventArgs e)
{
    using (var myRequestService = HostContext.ResolveService<MyRequestService>(new BasicRequest()))
    {
        myRequestService.Any(e.Request);
    }
}

并且确实找到了 MyRequestService 并调用了 Any,并且依赖项注入适用于该服务。

问题一:

  • 方法如OnBeforeExecute, OnAfterExecute等,不会被调用,除非我手动调用它们,例如:myRequestService.OnBeforeExecute(e)等等。管道的哪些部分丢失了?是否可以通过某种简单的方式恢复它,这样我就不必按顺序手动调用它们中的每一个?

问题2:

我认为当我这样做时我弄乱了 DI 系统:

using (var myRequestService = HostContext.ResolveService<MyRequestService>(new BasicRequest()))
{
    myRequestService.OnBeforeExecute(e.Request);
    myRequestService.Any(e.Request);
    myRequestService.OnAfterExecute(e.Request);
}

我看到的效果是我注册的注入依赖项container.AddScoped,没有范围,但看起来是静态的。我看到这一点是因为我在注入的类中有一个 Guid,并且在这种情况下该 Guid 始终相同,而每个请求的 Guid 应该不同。

container.AddScoped<IRedisCache, RedisCache>();

OnBeforeExecute(Service 的后代)类似于:

public override void OnBeforeExecute(object requestDto)
{
    base.OnBeforeExecute(requestDto);
    IRedisCache cache = TryResolve<IRedisCache>();
    cache?.SetGuid(Guid.NewGuid());
}

因此,IRedisCache Guid 每次都应该不同,但事实并非如此。然而,当我“从头到尾”使用 Messaging API 时,这工作得很好。看来,如果我在 AppHostBase 后代中调用 TryResolve,则会忽略 AddScoped,并将一个实例放置在容器中,然后永远不会删除。


管道的哪些部分丢失了?

没有任何一个请求管道 https://docs.servicestack.net/order-of-operations被执行:

myRequestService.Any(e.Request);

仅在物理上调用Any你的C#方法MyRequestService类,它不(也不不能)做任何其他事情。

在服务请求期间调用其他服务的推荐方法是使用服务网关 https://docs.servicestack.net/service-gateway.

但是如果您想在 HTTP 请求之外调用服务,您可以使用RPC网关 https://docs.servicestack.net/order-of-operations#rpcgateway用于执行不可信服务,因为它调用完整的请求管道并将 HTTP 错误响应转换为类型化错误响应:

HostContext.AppHost.RpcGateway.ExecuteAsync()

要在服务请求之外执行内部/可信服务,您可以使用HostContext.AppHost.ExecuteMessage https://docs.servicestack.net/order-of-operations#mq-non-http-custom-hooks由 ServiceStack MQ 使用,它应用消息请求请求/响应过滤器、服务操作过滤器和事件。

我已经注册了container.AddScoped

不使用HTTP 请求之外的请求范围依赖项 https://forums.servicestack.net/t/hostcontext-resolveservice-idisposable/7809/2?u=mythz,如果依赖项是ThreadSafe,则使用Singleton,否则将它们注册为Transient。如果您需要传递每个请求的存储,请传递它们IRequest.Items.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ServiceStack:手动调用服务时恢复管道? 的相关文章

  • Redis 块推送直到列表有空位

    我正在寻找类似的东西BLPUSH该命令将阻塞 直到列表的长度低于指定值max size 目的是防止生产者运行速度快于消费者时列表无限增长 功能与 python 非常相似Queue put https docs python org 3 li
  • Stackexchange.redis 缺乏“WAIT”支持

    我在客户端应用程序正在使用的负载均衡器后面有 3 个 Web API 服务器 我正在使用这个库来访问具有一个主服务器和几个从服务器的 Redis 集群 目前不支持 WAIT 操作 我需要此功能来存储新创建的用户会话并等待它复制到所有从属服务
  • 我的 Redis 自动生成的密钥

    我不知道我的 Redis 版本 4 0 9 到底发生了什么 我正在运行一个应用程序并使用 Redis 来存储我的数据库 但是 然后 Redis 自动创建 3 个新键 Backup1 Backup2 Backup3 并删除我的所有数据 这是我
  • 如何在多个Lua State(多线程)之间传递数据?

    我在中启动Redis连接池redis lua 通过从 C 调用 我得到了redis lua state 此 Lua 状态全局启动一次 仅在其他线程中启动get从中 当有一个 HTTP 请求 工作线程 时 我需要从redis lua stat
  • 将 RavenDB 与 ServiceStack 结合使用

    I read this http www philliphaydon com 2012 06 using nhibernate with servicestack Phillip Haydon 发表的有关如何将 NHibernate Rav
  • 为什么Redis中不建议使用KEYS?

    在Redis中 建议不要使用按键命令 https redis io commands KEYS 为什么会这样呢 是因为它的时间复杂度是 O N 吗 或者是别的什么原因 我做了下面的实验来证明KEYS命令有多么危险 当带有 KEYS 的一个命
  • 通过 jQuery tiny PubSub 传递数组

    jQuery 微型 PubSub https gist github com 661855在传递原始值或对象时非常有用 但在传递数组时会遇到一些问题 所以我必须将数组包装成一个对象 function var o subscribe func
  • 是否有可嵌入的 Java 替代 Redis?

    根据这个线程 https stackoverflow com questions 3047010 best redis library for java 如果我想从Java中使用Redis Jedis是最好的选择 然而 我想知道是否有任何库
  • ZeroMQ,我们可以使用 inproc: 传输以及 pub/sub 消息传递模式吗

    设想 我们正在评估ZeroMQ 具体来说jeroMq 用于事件驱动机制 应用程序是分布式的 其中多个服务 发布者和订阅者都是服务 可以存在于同一个 jvm 中或不同的节点中 这取决于部署架构 观察 为了玩玩我创建了一个pub sub图案与i
  • redis 阻塞直到 key 存在

    我是 Redis 新手 想知道是否有办法能够await get通过它的键来获取值 直到该键存在 最小代码 async def handler data await self fetch key async def fetch key ret
  • 通过 StackExchange.Redis 连接到 Redis Servier

    我尝试使用以下方法制作一个测试项目Redis https redis io服务器 通过 Virtual Box 安装在 Linux Ubuntu 虚拟机上 Linux 机器通过 Virtual Box 的桥接适配器与本地网络连接 Virtu
  • 在 aws-elasticache 上使用 memcached 或 Redis

    我正在 AWS 上开发一个应用程序 并使用 AWS elasticache 进行缓存 我对使用 memcached 或 redis 感到困惑 我阅读了有关 redis 3 0 2 更新以及它现在如何等同于 memchached 的文章 ht
  • Redis Docker compose无法处理RDB格式版本10

    我无法在 docker compose 文件中启动 redis 容器 我知道docker compose文件没问题 因为我的同事可以成功启动项目 我读到有一个删除 dump rdb 文件的解决方案 但我找不到它 我使用Windows机器 任
  • Redis发布/订阅:查看当前订阅了哪些频道

    我目前有兴趣查看我拥有的 Redis 发布 订阅应用程序中订阅了哪些频道 当客户端连接到我们的服务器时 我们将它们注册到如下所示的通道 user user id 这样做的原因是我希望能够看到谁 在线 目前 我在不知道客户端是否在线的情况下盲
  • 如何在Redis中从hmset()切换到hset()?

    我收到弃用警告 即 Redis hmset 已弃用 请改用 Redis hset 但是 hset 采用第三个参数 我不知道是什么name应该是 info users 10 timestamp datetime utcnow strftime
  • Redis、会话过期和反向查找

    我目前正在构建一个网络应用程序 并想使用 Redis 来存储会话 登录时 会话会使用相应的用户 ID 插入到 Redis 中 并且过期时间设置为 15 分钟 我现在想实现会话的反向查找 获取具有特定用户 ID 的会话 这里的问题是 由于我无
  • 有没有办法用Lettuce自动发现Redis集群中新的集群节点IP

    我有一个Redis集群 3主3从 运行在一个库伯内斯簇 该集群通过Kubernetes 服务 Kube 服务 我将我的应用程序服务器连接到 Redis 集群 使用Kube 服务作为 URI 通过 Redis 的 Lettuce java 客
  • Laravel 所有会话 ID 与 Redis 驱动程序

    在我的应用程序中 我希望允许某些用户能够注销除他 她之外的所有其他用户 当会话驱动程序设置为文件时 我已经完成了此功能 但现在我使用 redis 作为会话驱动程序 并且我无法找到任何方法来列出所有当前会话 就像我在文件时所做的那样司机 问题
  • Redis是如何实现高吞吐量和高性能的?

    我知道这是一个非常普遍的问题 但是 我想了解允许 Redis 或 MemCached Cassandra 等缓存 以惊人的性能极限工作的主要架构决策是什么 如何维持连接 连接是 TCP 还是 HTTP 我知道它完全是用C写的 内存是如何管理
  • 使用 Celery 通过 Gevent 进行实时、同步的外部 API 查询

    我正在开发一个 Web 应用程序 该应用程序将接收用户的请求 并且必须调用许多外部 API 来编写对该请求的答案 这可以直接从主 Web 线程使用 gevent 之类的东西来扇出请求来完成 或者 我在想 我可以将传入的请求放入队列中 并使用

随机推荐