-
Notifications
You must be signed in to change notification settings - Fork 0
/
ServerConnectionManager.scala
60 lines (48 loc) · 1.95 KB
/
ServerConnectionManager.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package org.hyperscala
import com.outr.scribe.Logging
import io.undertow.websockets.WebSocketConnectionCallback
import io.undertow.websockets.core.{AbstractReceiveListener, BufferedTextMessage, WebSocketChannel, WebSockets}
import io.undertow.websockets.spi.WebSocketHttpExchange
class ServerConnectionManager(val app: WebApplication) extends WebSocketConnectionCallback with ConnectionManager {
private val currentConnection = new ThreadLocal[Option[Connection]] {
override def initialValue(): Option[Connection] = None
}
private var _connections = Set.empty[Connection]
override def connections: Set[Connection] = _connections
override def connectionOption: Option[Connection] = currentConnection.get()
override def init(): Unit = {}
override def onConnect(exchange: WebSocketHttpExchange, channel: WebSocketChannel): Unit = {
logger.info("WebSocket connected!")
val connection = new ServerConnection(this, channel)
synchronized {
_connections += connection
}
channel.getReceiveSetter.set(connection)
}
def using[R](connection: Connection)(f: => R): R = {
currentConnection.set(Option(connection))
try {
f
} finally {
currentConnection.remove()
}
}
}
class ServerConnection(manager: ServerConnectionManager, channel: WebSocketChannel) extends AbstractReceiveListener with Connection with Logging {
override def app: WebApplication = manager.app
override def init(): Unit = {}
override def send(id: Int, json: String): Unit = WebSockets.sendText(s"$id:$json", channel, None.orNull)
override def onFullTextMessage(channel: WebSocketChannel, message: BufferedTextMessage): Unit = {
val data = message.getData
val index = data.indexOf(':')
if (index == -1) {
logger.error(s"Ignoring invalid message: $data")
} else {
val id = data.substring(0, index).toInt
val json = data.substring(index + 1)
manager.using(this) {
receive(id, json)
}
}
}
}