我正在尝试使用Akka HTTP的“服务器发送事件”功能来做一些Web应用程序。
TL; DR :我可以从浏览器运行和使用SSE,但是如果我只有一页并且刷新或退出并重新加载页面,则SSE入口点似乎不再起作用因为服务器端的整个Akka流看起来都是关闭的。
我在这里创建了一个项目:
https://github.com/totetmatt/wallemoji/tree/master/src/main/scala/fr/totetmatt/wallemoji
我基于此博客的第一部分(+改编自旧版本的akka) http://loicdescotte.github.io/posts/play-akka-streams-twitter/
在这里,我正在创建一个ActorRef源,它将接收一些事件并将其放置在Sink Publisher中
val (actorRef, publisher) = Source.actorRef[Status](1000, OverflowStrategy.dropHead)
.toMat(Sink.asPublisher(true))(Keep.both)
.run()
val statusListener = new StatusListener() {
override def onStatus(status: Status) = {
actorRef ! status
}
override def onDeletionNotice(statusDeletionNotice: StatusDeletionNotice): Unit = {
// System.err.println(statusDeletionNotice)
}
override def onTrackLimitationNotice(numberOfLimitedStatuses: Int): Unit = {
System.err.println(numberOfLimitedStatuses)
}
override def onScrubGeo(userId: Long, upToStatusId: Long): Unit = {
基于文档https://doc.akka.io/docs/akka-http/current/sse-support.html,我正在从发布商创建一个生成SSE流的源
~ path("twitter") {
get {
complete {
Source.fromPublisher(publisherTweet)
.map(s=>EmojiParser.extractEmojis(s.getText))
.mapConcat(l =>JavaConverters.asScalaIteratorConverter(l.iterator()).asScala.toSet )
.map(x=>ServerSentEvent(x,"emoji"))
.keepAlive(5.second, () => ServerSentEvent.heartbeat)
}
}
我在客户端使用这里的数据
http://github.com/totetmatt/wallemoji/blob/master/templates/index.html#L78-L96
source.addEventListener("emoji", function(e) {
//console.log(e)
var col = getRandomIntInclusive(1,15)
var div = document.createElement("div");
div.classList.add("cell");
div.classList.add("animated");
div.classList.add("fadeInDown");
div.innerHTML = e.data
document.getElementById("col_"+col).prepend(div);
此额外的 hacky 行使应用程序按预期运行
Source.fromPublisher(publisherTweet).runWith(Sink.ignore)
如果对此行进行了注释/删除,我可以首次连接,可以并行打开尽可能多的网页,而不会出现任何问题。但是,只要没有更多页面正在加载数据,源就似乎停止了并且正在生成该日志
INFO] [10/23/2018 08:29:09.858] [wall-emoji-akka.actor.default-dispatcher-2] [akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource] Message [twitter4j.StatusJSONImpl] without sender to Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877] was not delivered. [1] dead letters encountered. If this is not an expected behavior, then [Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877]] may have terminated unexpectedly, This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[INFO] [10/23/2018 08:29:09.860] [wall-emoji-akka.actor.default-dispatcher-14] [akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource] Message [twitter4j.StatusJSONImpl] without sender to Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877] was not delivered. [2] dead letters encountered. If this is not an expected behavior, then [Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877]] may have terminated unexpectedly, This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[INFO] [10/23/2018 08:29:09.863] [wall-emoji-akka.actor.default-dispatcher-14] [akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource] Message [twitter4j.StatusJSONImpl] without sender to Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877] was not delivered. [3] dead letters encountered. If this is not an expected behavior, then [Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877]] may have terminated unexpectedly, This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[INFO] [10/23/2018 08:29:09.863] [wall-emoji-akka.actor.default-dispatcher-14] [akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource] Message [twitter4j.StatusJSONImpl] without sender to Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877] was not delivered. [4] dead letters encountered. If this is not an expected behavior, then [Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877]] may have terminated unexpectedly, This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[INFO] [10/23/2018 08:29:09.871] [wall-emoji-akka.actor.default-dispatcher-2] [akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource] Message [twitter4j.StatusJSONImpl] without sender to Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877] was not delivered. [5] dead letters encountered. If this is not an expected behavior, then [Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877]] may have terminated unexpectedly, This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[INFO] [10/23/2018 08:29:09.877] [wall-emoji-akka.actor.default-dispatcher-2] [akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource] Message [twitter4j.StatusJSONImpl] without sender to Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877] was not delivered. [6] dead letters encountered. If this is not an expected behavior, then [Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877]] may have terminated unexpectedly, This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[INFO] [10/23/2018 08:29:09.891] [wall-emoji-akka.actor.default-dispatcher-2] [akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource] Message [twitter4j.StatusJSONImpl] without sender to Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877] was not delivered. [7] dead letters encountered. If this is not an expected behavior, then [Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877]] may have terminated unexpectedly, This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[INFO] [10/23/2018 08:29:09.891] [wall-emoji-akka.actor.default-dispatcher-14] [akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource] Message [twitter4j.StatusJSONImpl] without sender to Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877] was not delivered. [8] dead letters encountered. If this is not an expected behavior, then [Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877]] may have terminated unexpectedly, This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[INFO] [10/23/2018 08:29:09.892] [wall-emoji-akka.actor.default-dispatcher-14] [akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource] Message [twitter4j.StatusJSONImpl] without sender to Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877] was not delivered. [9] dead letters encountered. If this is not an expected behavior, then [Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877]] may have terminated unexpectedly, This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
[INFO] [10/23/2018 08:29:09.892] [wall-emoji-akka.actor.default-dispatcher-14] [akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource] Message [twitter4j.StatusJSONImpl] without sender to Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877] was not delivered. [10] dead letters encountered, no more dead letters will be logged. If this is not an expected behavior, then [Actor[akka://wall-emoji/system/StreamSupervisor-0/flow-0-2-actorRefSource#1389184877]] may have terminated unexpectedly, This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown
据我了解,它的关闭事件是ActorRef Source,如果没有更多的客户使用最后一个SSE Source。
我可以理解每个连接生成的Source是关闭的,但是为什么要一直沿图向上关闭所有内容?
是否有更好的方法来避免此ActorRef被关闭?还是这样的代码有什么问题呢?