webSocket
import net.http.*
import encoding.url.*
import std.time.*
import std.sync.*
import std.collection.*
import std.log.*
let server = ServerBuilder()
.addr("127.0.0.1")
.port(0)
.build()
// client:
main() {
// 1 Starts the server.
spawn { startServer() }
sleep(Duration.millisecond * 200)
let client = ClientBuilder().build()
let u = URL.parse("ws://127.0.0.1:${server.port}/webSocket")
let subProtocol = ArrayList<String>(["foo1", "bar1"])
let headers = HttpHeaders()
headers.add("test", "echo")
// 2 Completes handshake with WebSocket and obtains the WebSocket instance.
let websocket: WebSocket
let respHeaders: HttpHeaders
(websocket, respHeaders) = WebSocket.upgradeFromClient(client, u, subProtocols: subProtocol, headers: headers)
client.close()
println("subProtocol: ${websocket.subProtocol}") // fool1
println(respHeaders.getFirst("rsp") ?? "") // echo
// 3 Sends and receives a message.
// Sends "hello".
websocket.write(TextWebFrame, "hello".toArray())
// Receives a message.
let data = ArrayList<UInt8>()
var frame = websocket.read()
while(true) {
match(frame.frameType) {
case ContinuationWebFrame =>
data.appendAll(frame.payload)
if (frame.fin) {
break
}
case TextWebFrame | BinaryWebFrame =>
if (!data.isEmpty()) {
throw Exception("invalid frame")
}
data.appendAll(frame.payload)
if (frame.fin) {
break
}
case CloseWebFrame =>
websocket.write(CloseWebFrame, frame.payload)
break
case PingWebFrame =>
websocket.writePongFrame(frame.payload)
case _ => ()
}
frame = websocket.read()
}
println("data size: ${data.size}") // 4097
println("last item: ${String.fromUtf8(Array(data)[4096])}") // a
// 4 Closes WebSocket.
// Receives and sends CloseFrame.
websocket.writeCloseFrame(status: 1000)
let websocketFrame = websocket.read()
println("close frame type: ${websocketFrame.frameType}") // CloseWebFrame
println("close frame payload: ${websocketFrame.payload}") // 3, 232
// Closes the underlying connection.
websocket.closeConn()
server.close()
}
func startServer() {
// 1 Registers the handler.
server.distributor.register("/webSocket", handler1)
server.logger.level = OFF
server.serve()
}
// server:
func handler1(ctx: HttpContext): Unit {
// 2 Completes handshake with WebSocket and obtains the WebSocket instance.
let websocketServer = WebSocket.upgradeFromServer(ctx, subProtocols: ArrayList<String>(["foo", "bar", "foo1"]),
userFunc: {request: HttpRequest =>
let value = request.headers.getFirst("test") ?? ""
let headers = HttpHeaders()
headers.add("rsp", value)
headers
})
// 3 Sends and receives a message.
// Receives "hello".
let data = ArrayList<UInt8>()
var frame = websocketServer.read()
while(true) {
match(frame.frameType) {
case ContinuationWebFrame =>
data.appendAll(frame.payload)
if (frame.fin) {
break
}
case TextWebFrame | BinaryWebFrame =>
if (!data.isEmpty()) {
throw Exception("invalid frame")
}
data.appendAll(frame.payload)
if (frame.fin) {
break
}
case CloseWebFrame =>
websocketServer.write(CloseWebFrame, frame.payload)
break
case PingWebFrame =>
websocketServer.writePongFrame(frame.payload)
case _ => ()
}
frame = websocketServer.read()
}
println("data: ${String.fromUtf8(Array(data))}") // hello
// Sends 4,097 letters a.
websocketServer.write(TextWebFrame, Array<UInt8>(4097, item: 97))
// 4 Closes WebSocket.
// Receives and sends CloseFrame.
let websocketFrame = websocketServer.read()
println("close frame type: ${websocketFrame.frameType}") // CloseWebFrame
println("close frame payload: ${websocketFrame.payload}") // 3, 232
websocketServer.write(CloseWebFrame, websocketFrame.payload)
// Closes the underlying connection.
websocketServer.closeConn()
}
Running result:
subProtocol: foo1
echo
data: hello
data size: 4097
last item: a
close frame type: CloseWebFrame
close frame payload: [3, 232]
close frame type: CloseWebFrame
close frame payload: [3, 232]