vapor / websocket-kit

WebSocket client library built on SwiftNIO

Home Page:https://docs.vapor.codes/4.0/advanced/websockets/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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 )