You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Akka Typed Actor如何获取UDP发送方?无sender()方法的解决方案

Akka Typed中获取UDP发送方Actor Ref的方案

问题背景

在Akka Classic Actor中,存在sender()方法用于获取消息发送方。我使用akka.io.Udp实现向多个Actor进行UDP多播,以下是我的Akka Classic版本代码:

override def preStart(): Unit = {
  super.preStart()
  val manager = Udp(context.system).manager
  println(s"Sending req to bind to ${localInet}")
  manager ! Udp.Bind(self, localInet)
}

override def receive: Receive = {
  case Udp.Bound(localAddress) => {
    println(s"UdpConn Actor: ${sender()}")
    println(s"Bound to ${localAddress}")
    timers.startTimerWithFixedDelay("DISCOVERY", SendDiscovery, 1.seconds)
    context.become(ready(sender()))
  }
}

由于Akka Typed版本没有sender()方法,请问是否有办法获取UDP发送方的Actor Ref?我曾在Akka文档中搜索IO和UDP的Typed版本相关内容,但未找到相关信息。

解决方案

目前Akka官方并未为UDP IO提供原生的Typed封装,需要通过Classic-Typed适配工具实现需求,具体方案如下:

1. 导入适配工具包

引入Akka的Classic-Typed适配依赖后,导入相关适配包:

import akka.actor.typed.scaladsl.adapter._

2. 在Typed Actor中与Classic UDP Manager交互

  • 获取Classic的UDP Manager ActorRef:
    val classicManager = context.system.classicSystem.actorOf(Udp.props())
    
  • 发送Udp.Bind请求时,将Typed Actor自身转换为Classic ActorRef:
    classicManager ! Udp.Bind(self.toClassic, localInet)
    

3. 获取UDP发送方的ActorRef

通过context.messageAdapter将Classic的UDP事件转换为Typed消息,同时借助适配后的context.sender()获取发送方:

// 创建消息适配器,转换UDP事件
val udpAdapter = context.messageAdapter[Udp.Event] {
  case bound: Udp.Bound =>
    // 将Classic发送方ActorRef转换为Typed ActorRef
    val senderTypedRef = context.sender().toTyped[Udp.Command]
    // 自定义Typed消息,携带发送方信息
    BoundCompleted(bound.localAddress, senderTypedRef)
}

// 向UDP Manager注册适配器
classicManager ! Udp.Register(udpAdapter.toClassic)

4. 备选方案:通过Classic代理Actor中转

如果直接适配不够直观,可以在Typed Actor中创建一个Classic代理Actor,由它处理UDP IO交互,再将发送方信息传递给Typed Actor:

// 在Typed Actor中创建Classic代理
val udpProxy = context.spawnClassicActor(Props(new Actor {
  override def receive: Receive = {
    case Udp.Bound(localAddress) =>
      // 获取发送方并转发给Typed Actor
      context.parent ! BoundResult(localAddress, sender())
    case other => context.parent ! other
  }
}), "udp-proxy")

// 向代理发送Bind请求
classicManager ! Udp.Bind(udpProxy, localInet)

通过上述方案,即可在Akka Typed中获取UDP发送方的ActorRef,完成多播相关操作。

内容的提问来源于stack exchange,提问作者tmm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 18:05:17