在JavaScript和Python中,我在工作中使用了很多其他两种语言,设置WebSocket服务器(或客户端)和发送/接收消息非常容易。
例如,请查看the js WS repo中复制的代码。只需使用此代码即可设置基于节点的WebSocket服务器:
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
console.log('received: %s', message);
});
ws.send('something');
});
然后我可以接受ws
连接对象并将其传递给某个worker并随时发送回消息。我可以手动ws.send("Batch 123 Complete")
,例如,让我们的UI显示。没问题。
在Scala中,无论我使用的是http4s还是akka-http,这似乎都是不可能的。也许我太愚蠢无法弄明白了(可能!),但我花了很多时间在http4s gitter并阅读大量文档(fs2,射击我),并且唯一的Scala WS解决方案似乎基于流:你从一个客户端源,一个toClient源,连接它们,就是这样。您无法从服务器端手动执行与ws.send('some info!')
等效的Scala。
http4s gitter中一个非常善良的人甚至把this example放在一起试图帮助我解决我正在做的事情,但最终似乎没有。这非常客户要求 - >服务器响应设置。它似乎无法随时向客户端发送消息。
我完全错过了这个吗?我希望我有,因为我花了几天时间学习http4s套接字和fs2,并推出了基于流的实现,它基于fs2的Scheduler。当客户端打开与我的WS服务器的连接时,它会生成一个worker并每秒发送回状态消息,但我不喜欢它:/我的代码中需要的可变变量。
非常感谢任何提示或讨论。
答案 0 :(得分:1)
我同意HTTP4S的例子是疯了!
是否必须是HTTP4S或Akka HTTP?您可以使用Java-WebSocket库轻松完成此任务:
val s = new WebSocketServer(address) {
override def onOpen(webSocket: WebSocket,
clientHandshake: ClientHandshake): Unit = {
// keep 'webSocket' around and push messages to it
}
override def onClose(webSocket: WebSocket,
code: Int,
reason: String,
remote: Boolean): Unit =
// remove the reference to 'webSocket'
override def onMessage(webSocket: WebSocket, message: String): Unit =
println("Received something from the client")
override def onError(webSocket: WebSocket, e: Exception): Unit = ???
override def onStart(): Unit = ???
}