Closed EugeneSid closed 2 years ago
Hi, thanks a lot for this report and the details in it.
By using krossbow STOMP client library I receive "GET" command only with URL and headers which doesn't have STOMP initial commands (STOMP or CONNECT) but instead it looks like WEB STOMP version
Could you please clarify what you mean by "WEB STOMP"? Do you mean this?
I think this might be the source of the issue here. STOMP is an application-level protocol, so it needs a transport. The STOMP or CONNECT frame is sent on the wire via this transport. The protocol specification doesn't force the use of a particular network protocol underneath, but usually it's raw TCP or web socket. Web sockets are convenient because they already provide some framing on top of TCP.
Krossbow is a STOMP client using web socket as transport (or an emulated version of websocket via SockJS). In order to send STOMP frames (like STOMP or CONNECT), the Krossbow client first needs to connect at the web socket level. This is done via an HTTP request with an Upgrade
header (as defined by the websocket RFC).
Does your STOMP server only support raw TCP connections?
Sorry for delay..
Could you please clarify what you mean by "WEB STOMP"? Do you mean this?
Yes, right.
Does your STOMP server only support raw TCP connections?
I checked CoilMQ STOMP server and I see that it listens for web socket frames. CoilMQ STOMP server received that "GET" command inside a socket frame. But this is the only command it gets. No other frames are coming - so no connection frame (STOMP or CONNECT command).
CoilMQ STOMP server received that "GET" command inside a socket frame.
Now that is quite unexpected. I'm sorry to ask you for more, but you could you please share the code using Krossbow to connect to the server? I would really like to be able to understand or reproduce the issue myself.
Yes sure.
private val RPI_EM_LOCALHOST = "172.18.5.38"
private val SERVER_PORT = "61613"
private var WEBSOCKET_TOPIC = "/queue/cam"
private var WEBSOCKET_URI = "ws://$RPI_EM_LOCALHOST:$SERVER_PORT"
@Inject
lateinit var stompClient: StompClient
@Inject
lateinit var stompSession: StompSession
private fun connectToEm() { //called from init function
lifecycleScope.launch {
try {
//val webSocket = OkHttpWebSocketClient(okHttpClient)
stompClient = StompClient(KtorWebSocketClient())
stompSession = stompClient.connect(
"$WEBSOCKET_URI$WEBSOCKET_TOPIC",
"admin",
"password"
)
} catch (ex: Exception) {
when (ex) {
is WebSocketConnectionException, is ClassNotFoundException -> {
Log.e("Error:", ex.message.toString())
}
else -> throw ex
}
}
}
}
This is separated simplified part of code for RPi connection test but has problem described above.
Thanks a lot for the quick response and the extra code.
I checked CoilMQ STOMP server and I see that it listens for web socket frames.
My Python level is close to 0, but from what I can see in the CoilMQ code, they really are just streaming a TCP connection without any web socket layer.
request
is at that point)FrameBuffer
This explains why this server doesn't speak HTTP nor websocket, it is a raw TCP server. When receiving an HTTP request to open a web socket connection, the server tries to interpret the raw bytes of the HTTP protocol as a STOMP frame and fails.
Unfortunately Krossbow is a client that relies on web socket at the moment, and it is not a short term goal to support raw TCP sockets. That said, I could consider implementing it if you need it.
Now everything became clear thanks to you. I think I'd looking for some other solution for CoilMQ communication. I really appreciate your help and I'll keep monitoring krossbow updates at least because we are using it in our main project and it works well. Also I really like how quick and good support are. Thanks a lot!
That's heartwarming, thanks! I try to do my best, and this kind of message really motivates me to do more!
I hope you'll find a nice alternative for this use case. Have a good one!
Thanks a lot for the quick response and the extra code.
I checked CoilMQ STOMP server and I see that it listens for web socket frames.
My Python level is close to 0, but from what I can see in the CoilMQ code, they really are just streaming a TCP connection without any web socket layer.
- they seem to use a raw TCPServer here
- here they receive raw bytes (it's still unclear to me what
request
is at that point)- here they directly append the raw bytes (without framing) to their custom
FrameBuffer
- then in extract_frame they directly read the raw bytes from the buffer until they get a complete STOMP frame - no websocket frame involved.
This explains why this server doesn't speak HTTP nor websocket, it is a raw TCP server. When receiving an HTTP request to open a web socket connection, the server tries to interpret the raw bytes of the HTTP protocol as a STOMP frame and fails.
Unfortunately Krossbow is a client that relies on web socket at the moment, and it is not a short term goal to support raw TCP sockets. That said, I could consider implementing it if you need it.
It would be really helpful for me, I'm trying to consume a STOMP server using raw TCP sockets.
Thanks for letting me know. I opened the following issue, which you can upvote: https://github.com/joffrey-bion/krossbow/issues/287
I'm using STOMP for interaction between android device and raspberry pi. As a server I have Coilmq STOMP server this installed on RPi4 and successfully tested with stomp.py - a python library of STOMP client.
By using krossbow STOMP client library I receive "GET" command only with URL and headers which doesn't have STOMP initial commands (STOMP or CONNECT) but instead it looks like WEB STOMP version:
And because of this I'm unable to connect to the server.. Android log info:
The coilmq log shorted info:
On the other hand, when I run python STOMP client, there is STOMP command and the message looks like:
And after that I'm successfully connected to the server.
Stomp client have been build on KtorWebSocketClient as in official documentation and using that I attempted to connect via local network.
Any Idea what I'm doing wrong? Thank you!