onBinary Usage?
xanderdunn opened this issue · comments
Ubuntu 18.04, websocket-kit 2.1.1
Swift for Tensorflow 0.10
$ which swift
home/xander/swift-tensorflow-RELEASE-0.10-cuda10.2-cudnn7-ubuntu18.04/usr/bin/swift
$ swift --version
Swift version 5.3-dev (LLVM 55d27a5828, Swift 6a5d84ec08)
Target: x86_64-unknown-linux-gnu
I have been successfully using the onText
callback to parse the messages my web socket client receives. However, when I replace this with onBinary
, I never receive anything. It's never called. I expected onBinary
would be called with the same data simply as a ByteBuffer
rather than first decoding it to a String
. What is the expected usage of onBinary
? If this is not a bug, in what cases is onBinary
expected to be called?
I would prefer to access the data via the original ByteBuffer
rather than as a converted String
because I will have to convert a String
back to bytes/Data
to do my decoding.
Text and Binary are two different opcodes in the websocket protocol, the two handler functions simply reflect that. If the client sends a text message, it is routed to onText, and binary messages are routed to onBinary.
How you actually get binary messages to be sent depends on the client, in JS as far as I can tell, you'll get binary messages if you send ArrayBuffers instead of strings directly. (The binaryType
property of the websocket might also play a role.)
Thanks @vzsg, that makes sense. In the Swift-NIO WebSocket example here, the case .text
situation still must decode the received frame.unmaskedData
to a String
. It is this raw data that I would like access to, prior to the readString
step. It looks like websocket-kit doesn't expose the data at this point and only passes the decoded String
to onText
. I will probably need to drop down to NIOWebSocket directly to achieve this. I don't imagine websocket-kit wants to change the behavior of onText
, so this can be closed.
Hey, I think it's still a solid feature request.
Hello, I tried to use onText to receive messages, but there was no response. This is the code I wrote. I don't know if I made a mistake. Can you give me a complete demo? Thank you very much.
import Vapor public func configure(_ app: Application) throws { try webs(app) try routes(app) } func webs(_ app: Application) throws { let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1) WebSocket.connect(to: "ws://echo.websocket.org", on: eventLoopGroup ) { ws in ws.onText { ws, text in print(text) } ws.onBinary { ws, binary in print(binary) } } }
@shenfu1991 There are a few mistakes there, including creating a new MultiThreadedEventLoopGroup instead of using the app
's, not starting this new group (but this point is moot, since you shouldn't be making one in the first place), and not sending anything to the socket that would be echoed back.
Using on: app.eventLoopGroup
and actually sending something on the socket makes it work:
private func webs(_ app: Application) {
WebSocket.connect(to: "wss://echo.websocket.org", on: app.eventLoopGroup) { (ws) in
print("CONNECTED!")
ws.onText { _, text in
print("Received text: \(text)")
}
ws.onBinary { _, bin in
print("Received binary message: \(bin)")
}
ws.send("Sup!")
ws.send([1,2,3,4,5])
}
}
Results in the following output:
CONNECTED!
Received text: Sup!
Received binary message: ByteBuffer { readerIndex: 0, writerIndex: 5, readableBytes: 5, capacity: 8, storageCapacity: 8, slice: _ByteBufferSlice { 0..<8 }, storage: 0x00000001027343c0 (8 bytes) }
That all being said, please don't hijack other issues with questions.
Either open a new issue, or even better: hit up Vapor's Discord server.
Closing this as I think it's agreed it's solved (and likely further amplified by #116 )