Skip to content
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

[Android & Node.js Server] Problem using PerMessageDeflateExtension with custom ping/pong messages ? #1164

Closed
SaraHan774 opened this issue Jul 21, 2021 · 5 comments · Fixed by #1165
Labels
Milestone

Comments

@SaraHan774
Copy link

SaraHan774 commented Jul 21, 2021

Hi, I have a question about using PerMessageDeflateExtension.

E/SessionManager: ◖[Session] WebSocket error #Network	⚑[SessionManager$listenToEvents$6.accept:358]
E/SessionManager: ◖ org.java_websocket.exceptions.InvalidFrameException: RSV1 bit must be set for DataFrames.
E/SessionManager: ◖	at org.java_websocket.extensions.permessage_deflate.PerMessageDeflateExtension.isFrameValid(PerMessageDeflateExtension.java:321)
E/SessionManager: ◖	at org.java_websocket.drafts.Draft_6455.translateSingleFrame(Draft_6455.java:565)
E/SessionManager: ◖	at org.java_websocket.drafts.Draft_6455.translateFrame(Draft_6455.java:739)
E/SessionManager: ◖	at org.java_websocket.WebSocketImpl.decodeFrames(WebSocketImpl.java:398)
E/SessionManager: ◖	at org.java_websocket.WebSocketImpl.decode(WebSocketImpl.java:233)
E/SessionManager: ◖	at org.java_websocket.client.WebSocketClient.run(WebSocketClient.java:516)
E/SessionManager: ◖	at java.lang.Thread.run(Thread.java:923)
E/SessionManager: ◖ 

I ran into above error log, so I made a break point like below.

image

image

If you see the log, the payload contains our custom ping message which is being transferred in TextFrame. I would like to know if this kind of custom ping/pong message could interfere with using PerMessageDeflateExtensions properly. (I checked the RFC 6455 document and read that Ping/Pong Frames have different opcodes)

Also, I couldn't understand the purpose of the below lines.

    public void isFrameValid(Framedata inputFrame) throws InvalidDataException {
        if((inputFrame instanceof TextFrame || inputFrame instanceof BinaryFrame) && !inputFrame.isRSV1())
            throw new InvalidFrameException("RSV1 bit must be set for DataFrames.");

Does this mean that all TextFrame & BinaryFrame data should have isRSV1() set to true ? If so, how does it handle situations when server compresses data selectively?

Best Regards,
Sara.


  • Java-WebSocket Version 1.5.2
  • Java 1.8
  • Node.js uses ws websocket library
@marci4
Copy link
Collaborator

marci4 commented Jul 21, 2021

Hey
Could you provide an example application for both java and node js?

I may have to recheck the specification but I thought it is only compressed or uncompressed. Mixing not allowed.

Best regards,
Marcel

EDIT: I have to be corrected.
This document allocates the RSV1 bit of the WebSocket header for PMCEs and calls the bit the "Per-Message Compressed" bit. On a WebSocket connection where a PMCE is in use, this bit indicates whether a message is compressed or not.

@marci4 marci4 added the Bug label Jul 21, 2021
@SaraHan774
Copy link
Author

SaraHan774 commented Jul 21, 2021

Node.js Server added below code for supporting permessage-deflate. transformer: 'websockets' indicates that the server will use ws module for websocket. https://github.com/primus/primus#websockets

const primus = new Primus(createHttpServer(...), {
  transformer: 'websockets',
  compression: true, 
... 

image

compression : true enables permessage deflate.

In android, there is a WebSocketClient like below,

internal class WebSocketManager(private val wssUrl: URI) {
    companion object {
...
        // For receiving compressed data from the server
        private val perMessageDeflateDraft = Draft_6455(PerMessageDeflateExtension())
    }

    private inner class Client : WebSocketClient {
        constructor(wssUrl: URI) : super(wssUrl)
        constructor(wssUrl: URI, perMessageDeflateDraft: Draft_6455) : super(
            wssUrl,
            perMessageDeflateDraft
        )
...

// overrided functions from WebSocketClient ... 
    }

And when calling WebSocketManager.connect(), the client object is initialized like this

fun connect(): Boolean {
...
            client = Client(wssUrl, perMessageDeflateDraft).apply {
                connectionLostTimeout = DEFAULT_CONNECTION_CHECK_INTERVAL
                addHeader(USER_AGENT_HEADER_NAME, getUserAgentString())
            }
            client!!.connect()
...
}

For the android part, I basically followed this library's wiki on PerMessageDeflateExtension.

marci4 added a commit to marci4/Java-WebSocket-Dev that referenced this issue Jul 25, 2021
@marci4 marci4 added this to the Release 1.5.3 milestone Jul 25, 2021
@SaraHan774
Copy link
Author

@marci4 Hi, is 1.5.3 scheduled for release in the near future?

@PhilipRoman
Copy link
Collaborator

FYI: you don't have to wait for new releases, you can always use https://oss.sonatype.org/content/repositories/snapshots/org/java-websocket/Java-WebSocket/1.5.3-SNAPSHOT/ or Jitpack (https://jitpack.io/#TooTallNate/Java-WebSocket/master-SNAPSHOT)

@SaraHan774
Copy link
Author

Thank you for the answer!

Best Regards, Sara.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants