-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to send Uint8List (version 3.8) #56
Comments
Hey, it looks like the SockJS protocol does not support sending binary messages: So our parser does not support this. My suggestion if you need binary support: Use plain Stomp without SockJS as a wrapper protocol |
Thanks a lot. I am sorry for bothering. It seems my issue was based on my faulty understanding of websockets and sockjs. I will therefore close this issue. Might i ask a small question ? I noticed that large text messages such as base64 encoded images are not recieved from my spring backend. Neither do they cause any response nor exception from the following callbacks: if (stompClient == null) {
stompClient = StompClient(
config: StompConfig(
url: socketUrl,
onConnect: onConnect,
onWebSocketError: (dynamic error) => print(error.toString()),
onStompError: (dynamic error) => print(error.toString()),
onUnhandledMessage: (dynamic error) => print(error.toString()),
)); Now i have already tried to increase the message size in my spring backend by overriding the configureWebSocketTransport method. override fun configureWebSocketTransport(registration: WebSocketTransportRegistration) {
registration.setMessageSizeLimit(1024 * 1024 * 200) // default : 64 * 1024
registration.setSendTimeLimit(20 * 10000) // default : 10 * 10000
registration.setSendBufferSizeLimit(1024 * 1024 * 200) // default : 512 * 1024
super.configureWebSocketTransport(registration)
} Yet this did not have the expected effect and when sending a large text message there is not even a error / response from the server. Am i missing another configuration step in the client or is there another possible cause. I have read here: https://stackoverflow.com/questions/38325807/java-sockjs-spring-client-and-message-size that the cause might be a faulty configured client. Since this is possibly not the right place to ask such a question i fully understand if there is now answer. Thanks for your help. |
Hey, do happen to have a sample body i could use to test this out? In the meantime, could you try to enable TRACE logging for the your WebSockets in spring: This could help to see errors/problems when the server receives your message. |
Hi, the message body is simply this string formed by base64 encoding a public available image found in the internet since the image is about 85 kb in size and base64 encoding increases the size by around 30 percent i would assume that the string contains around 110 kb. As for the flutter way how i encoded this: void sendImage() async {
var file = await selectImage();
List<int> imageBytes = file.readAsBytesSync();
var base64Image = base64.encode(imageBytes);
if (file != null) {
stompClient.send(
destination: '/app/imageQueue',
body: base64Image,
);
print("done sending");
}
} I have listed the resulting string below if you want to paste it somewhere. |
Hey, i've looked into this a bit and it might be that Spring does need another configuration to accept those large buffer sizes. I've tested it on my own server and it also dropped the connection without showing any errors (even in the socket trace). The close reason given on the client was: "The decoded text message was too big for the output buffer and the endpoint does not support partial messages". Here is what i've changed (you probably also need your configuration from the first post):
This then at least gave me another error related to Stomp, so i am confident that this is no longer a limit on the client, but on the server. |
Hi, Thanks a lot. I found a similar post indicating the same on stackoverflow: https://stackoverflow.com/questions/21730566/how-to-increase-output-buffer-for-spring-sockjs-websocket-server-implementation Interestingly it seems that by adjusting the configureWebSocketTransport one can only adjust outgoing buffer not adjusting the actual buffer sizes for incoming messages. One more thing to add: I tested the websockets in Spring boot integration tests. They also did not return error messages on to low buffer sizes simply not returning anything. Likewise the server did not log anything even on log level trace. Since the problem (not recieving error messages) exists for Kotlin / Java Implementations of the client too, it seems to be non specific for the stomp client. It makes me wonder how the error was recieved on the experimental Postman feature tho. Anyway. Thank you for your kind help. |
I think it just notices that the connection was closed with a closeCode/reason which is erroneous, the same as i was able to determine why the connection was closed. |
Hello again, this kind of question is kind of unrelated to the message before and goes over the topic of simply using the flutter extension. Of course you can therefore simply chose to not answer. I am trying to utilize the binaryBody property of your package. The sending is done by a spring boot application which send the message via a SimpMessagingTemplate and the method: sendAndConvert. Neither sending the BinaryMessage (org.springframework.web.socket.BinaryMessage) nor sending plain Bytes (byte[] or ByteArray in Kotlin) nor sending a GenericMessage with byte Payload results in the binaryBody being filled. The result ist always the bytes being casted to a body property. fun messageClientQueueBytes(taskId: String, bytes: ByteArray) {
try {
var generic: GenericMessage<ByteArray> = GenericMessage<ByteArray>(bytes)
simpMessagingTemplate.convertAndSend("/queue/task/test", generic)
} catch (ex: Exception) {
logger.error("StreamService_messageClientQueue_ ${ex.message})")
}
} (example dart) (note i am not using sockjs config on server or client anymore) client.subscribe(
// destination: '/queue/task/${stream.id}',
destination: '/queue/task/test',
callback: (frame) {
/// Case: Its a image or file message
if (frame.binaryBody != null) {
BlocProvider.of<StreamBloc>(context)
.add(StreamUpdateRecieved(update: frame.binaryBody));
}
/// Case: Status Message sent
if (frame.body != null) {
Map<String, dynamic> result = json.decode(frame.body);
if (result['status'] == "SETUP FINISHED") {
BlocProvider.of<StreamBloc>(context).add(StreamSetupFinished());
startTimer();
}
}
}); do you happen to know what kind of message i have to send here to access the binaryBody or am i misunderstanding something ? Thanks in advance if you spend your time on this :) |
Hey, i think you need to specifically set the content type to "application/octet-stream" when converting and sending your message.
Note: I haven't tested this code, so consider this more or less pseudo code. |
0:"content-type" -> "application/octet-stream"
1:"destination" -> "/queue/task/test"
2:"subscription" -> "sub-0"
3:"message-id" -> "08ccf41b-cdf0-9444-bd0e-df16f688162f-0"
4:"content-length" -> "6" Did sadly still not work. Actually the content type was even set to application/octet-stream without changing the headers. Stillm thank you for your effort :) . |
Hey, i will check later today or in the next few days if i can set up a test case and see if i can make this work. |
Hey, i've looked into this a bit. It seems like our parser does never provide the |
Unable to send ByteArray in binary body property.
Version: 3.8
Cause: _TypeError (type 'Uint8List' is not a subtype of type 'String')
Where: sock_js_parser.dart
When: sending StompFrame with Uint8List property non null.
Use Case: Selecting image with FilePicker package and dart.io then sending it as byte array (non encoded for performance reasons)
The text was updated successfully, but these errors were encountered: