I have a web socket single write sampler followed by a web socket single read sampler in a while loop.
The challenge I am facing is that
This is how my test plan looks currently.
Thread Group
\_ Web socket open connection
\_ Web socket single write sampler
\_ While controller-1
\_ Web socket single read sampler-1 (text response filter)
\_ While controller-2
\_ Web socket single read sampler-2 (binary response filter)
\_ While controller-3
\_ Web socket single read sampler-3 (text response filter)
\_ While controller-4
\_ Web socket single read sampler-4 (binary response filter)
The thread errors out in case there is a text response coming in after the last binary response filter.
Any help on how to handle this scenario is appreciated.
Thanks in advance
Checkout version 1.2.8 of the plugin: this version adds an option so that the read sampler can receive text or binary (i.e. you don't have to specify upfront which data frame it should expect). https://bitbucket.org/pjtr/jmeter-websocket-samplers/issues/168/add-option-to-single-read-sampler-to-read
Related
The database i'm integrated is configured as if a connection is idle(not being used for a while), then connection is dropped. Since im using spring batch in persistent configuration, there is always an active database connection on running threads.
One of my spring batch job is dependent to data from external web service which takes long time to execute. Thats why i already lose the database connection when i get the result.
I tried to use taskscheduler to register a heartbeat query(select 1 from dual) before the web request occurs, which executes the queryevery 5 minutes to keep the connection alive but even if the query executes periodically, i guess it executes the query on a seperate connecyion since it runs on another thread.
Does anyone have an alternative suggestion to keep the connection alive while on locked thread?
I use JPA's EntityManager for the haertbeat query
If you use Spring then you also use HikariCP. The recent JDBC standard defines method isValid() so you do not have to call SQL to check whether Connection is alive.
More over there is one more mechanism you can use. It is called TCP keepalive.
If you insert stanza ENABLE=BROKEN into your JDBC url Oracle JDBC drivers will enable TCP Keepalive feature on a TCP connection
jdbc:oracle:thin:#(DESCRIPTION=(ENABLE=BROKEN)(ADDRESS=(PROTOCOL=tcp)(PORT=1521)(HOST=myhost))(CONNECT_DATA=(SERVICE_NAME=orcl)))
Then it will be Linux kernel who will be sending keepalive probes over TCP connection even if your thread is blocked.
Beware: The delay for 1st probe and frequency is determined by Linux kernel parameters.
# cat /proc/sys/net/ipv4/tcp_keepalive_time
7200
# cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75
# cat /proc/sys/net/ipv4/tcp_keepalive_probes
9
By default the 1st keep alive probe (TCP window carying 0 bytes) is sent after 2 hours.
While Cisco/Juniper usually cut off TCP connection after one hour.
I'm using Ubuntu 18.04 LTS with bash 4.4.20.
I'm trying to create a little daemon to schedule data transmission between threads.
On the server I am doing this:
ncat -l 2001 -k -c 'xargs -n1 ./atc-worker.sh'
On the client I am doing this:
echo "totally-legit-login-token" | nc 127.0.0.1 2001 -w 1
And it works well!
Here is the response:
LaunchCode=1589323120.957093305 = Now=1589323120.957093305 = URL=https://totally-legit-url.com/ = AuthToken=totally-legit-auth-token = LastID=167
When the server receives a request from a client, it calls my little atc-worker.sh script. The server spits out a single line of text and it is back to business, serving other clients.
Thanks to the -k option, the server listens continuously. Multiple clients can connect at the same time. The only problem, is that I cannot end the connection programmatically. I need the daemon -k functionality on the server to answer requests from the clients, but I need the clients to quit listening after receiving a response and get on to their other work.
Is there an EOF signal/character I can send from my atc-worker.sh script that would tell nc on the client side to disconnect?
On the client, I use the -w 1 option to tell the client to connect for no more than a second.
But this -w 1 option has some drawbacks.
Maybe a second is too long. The connection should just take ~150 milliseconds and waiting out the rest of the second slows each client down even if it already has its answer. And -as I said before- the client has chores to do! The client shouldn't be wasting its time after it has its answer!
Bad actors Rogue clients could connect to the server that have no intention to close out in a timely manner and I want the server to have better control and shut down bad actors.
Maybe a second is too short. atc-worker.sh has a mechanism to wait for a lock file to be removed if there is one. If that lock file is there for more than a second, the connection will close before the client can receive its response.
Possible solutions.
The atc-worker.sh script could send a magic character set to terminate the connection. Problem solved.
On the client-side set of solutions, maybe curl would be a suitable choice instead of nc? But it would not solve my concern of being able to deal with bad actors. Maybe these are two different problems? Client-side closing the connection immediately after an answer is received, and server-side dealing with bad actors who will use what ever clients they choose.
Maybe use expect? I'm investigating that now.
Thanks in advance!
OK. After a lot of digging, I found someone else with a similar problem. Here is a link to his answer.
Original question: Client doesn't close connection to server after receiving all responses
Original Answer: https://stackoverflow.com/a/50528286/3055756
Thanks #Unyxos
I modified my daemon to send an "ENDRESPONSE" line when it was done even though it does not drop the connection. And I modified the client to look for that "ENDRESPONSE" line. When the client gets the line, it drops the connection using the logic that #Unyxos uses below in his answer.
Here is his simple and elegant answer:
Finally found a working way (maybe not the best but at least it's perfectly doing what I want :D)
after all functions I send a "ENDRESPONSE" message, and on my client, I test if I have this message or not :
function sendMessage {
while read line; do
if [[ $line == "ENDRESPONSE" ]]; then
break
else
echo $line
fi
done < <(netcat "$ipAddress" "$port" <<< "$*")
}
Anyway thanks for your help, I'll try to implement other solutions later !
I am relatively new to JMeter however I have been doing Performance testing for almost a decade.
I am working with a proprietary TCP protocol that sends a keep alive periodically - through the existing TCP connection.
I am struggling to understand how I can fork the JMeter 'thread group' to handle a TCP Keep alive received over the same TCP session.
Any ideas?
Thank you brainstrust!
edit: I'm using the TCPsampler and have read the help page. I'll try to provide some more detail shortly about what's happening and how the protocol is written.
edit2: Unfortunately because it's a propriety protocol I cannot reveal the exact nature of the protocol itself but it's largely irrelevant to the problem I'm facing.
Basically, I use the 1st TCP sampler to 'start/authenticate' the session with the server. This is configured the following options:
1. TCPClient classname: LengthPrefixedBinaryTCPClientImpl (my protocol is implemented this standard way)
2. Re-use connection ON.
3. Close connection OFF.
4. Set NoDelay OFF.
5. SO_Linger: nothing
6. Text to send: my hex code for the protocol (this is correct)
I get the response from the first TCP request and then I want to start interacting, however in the session, the server sends a keep alive mid-stream, so occassionally when I send a request, I get an unexpected keep alive response instead (it's an open stream of data).
This is what I would like to solve.
I attempted to use a recursive test fragment, so that on KeepAlive response, it would send the request again however one cannot recurse the test fragments (it throws a Java error on Run attempt).
I hope this gives more context! Thank you for your patience (I'm a newbie SO user!)
Please check the below options if it helps with you sceario:-
If "Re-use connection" is selected, connections are shared between
Samplers in the same thread, provided that the exact same host name
string and port are used. Different hosts/port combinations will use
different connections, as will different threads. If both of "Re-use
connection" and "Close connection" are selected, the socket will be
closed after running the sampler. On the next sampler, another socket
will be created. You may want to close a socket at the end of each
thread loop.
If an error is detected - or "Re-use connection" is not selected - the
socket is closed. Another socket will be reopened on the next sample.
The following properties can be used to control its operation:
tcp.status.prefix text that precedes a status numbertcp.status.suffix
text that follows a status numbertcp.status.properties name of
property file to convert status codes to messagestcp.handler Name of
TCP Handler class (default TCPClientImpl) - only used if not specified
on the GUI
For more details:-https://jmeter.apache.org/usermanual/component_reference.html#TCP_Sampler
A few weeks ago I wrote a small program which created a socket to an apache webserver and made a request.
Back then I did not know that this web server had a KeepAliveTimeout of 5 seconds.
After my first request I waited 1 minute. After this I wanted to reuse my first socket for another webserver request, but got an error.
From Beej's Guide to Network Programming I learned that if recv returns 0, then the other side has closed its connection:
Wait! recv() can return 0. This can mean only one thing: the remote side has closed
the connection on you! A return value of 0 is recv()'s way of letting you know this
has occurred.
My questions are now:
What does Apache send when the KeepAliveTimeout is over - a FIN or a RST packet?
I know that using a TCP connection for 2 unrelated HTTP requests like in this scenario might
not be the best thing. But in order to understand TCP more the next question is:
After my first successful http request, and before sending the next HTTP request over the same socket, would there be somehow a possibility to get informed about this keepalivetimeout TCPsocket termination of the server other than receiving 0 from the next recv() call?
It will send a FIN. If you write a request to the server after that, send() will return -1 with errno/WSAGetLastError() = ECONNRESET.
would there be somehow a possibility to get informed about this keepalivetimeout tcp socket termination of the server
Yes, by reading the proper response header parameter, namely Keep-Alive: timeout=delta-seconds:
'timeout' Parameter
A host sets the value of the timeout parameter to the time that the host will allows an idle connection to remain open before it is closed. A connection is idle if no data is sent or received by a host.
The value of the timeout parameter is a single integer in seconds.
A host MAY keep an idle connection open for longer than the time that it indicates, but it SHOULD attempt to retain a connection for at least as long as indicated.
As you can see, it's up to the host to decide. Given it only SHOULD try to keep the connection open as long as promised, but it isn't required that it does in order to conform to the spec, so the server might decide to close and reuse the connection to serve another pending client.
I need to close UDP socket which has unsent data immediately.
There is SO_LINGER parameter for TCP sockets but I didn't find out anything for UDP.
It's on Windows.
Thanks in advance.
Update 0:
I give background of this question. I have application 1st thread opens/binds/closes socket, 2nd thread sends datagrams to it.
In some cases after closing the socket (errorcode = 0) bind function returns errorcode 10048 "Address already in use". I found out after close() execution port is still used (via netstat command). Maybe I ask incorrect question and the reason of such behavior is something else?
For all application purposes once your send() returns, the packet is "sent". There's no send-buffer like in TCP, and you have no control over the NIC packet queue. Normal close() is all you need.
Edit 0:
#EJP, here's a quote from UNP for you (Section 2.11 "UDP Output"):
This time, we show the socket send buffer as a dashed box bacause it
doesn't really exist. A UDP socket has a send buffer size (which we
can change with the SO_SNDBUF socket option, Section 7.5), but this
is simply an upper limit on the maximum-sized UDP datagram that can
be written to the socket. If an application writes a datagram larget
than the socket send buffer size, EMSGSIZE is returned. Since UDP is
unreliable, it does not need tp keep a copy of the application's data
and does not need an actual send buffer. (The application data is
normally copied into a kernel buffer of some form as it passes down
the protocol stack, but this copy is discarded by the datalink layer
after the data is transmitted.)
This is what I meant in my answer - you have no control over the send buffer - , so "for all application purposes" it does not exist.
I was having this problem with a windows UDP socket as well. After hours of trying everything I finally found my problem was that I was calling socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) on the main thread to create the socket, calling bind(...) and recvfrom() on a worker thread, then after closing the worker thread I called closesocket(...) on the main thread. None of the functions returned an error but tor some reason, doing this leaves the UDP address/port combination in use (so a future call to bind() triggers error 10048 WSAEADDRINUSE and netstat -abot -p UDP also shows the port still in use until the whole application is closed). The solution was to move socket(...) and closesocket(...) calls into the worker thread.
Other than weird issues like the case above, there is normally no way that a UDP server socket can be left open after calling closesocket() on it. Microsoft explains that there is no connection maintained with a UDP socket and no need to call shutdown() or any other function. Usually the reason a TCP socket is left open after calling closesocket() is that it wasn't disconnected gracefully and it's waiting for about 4 minutes in TCP_WAIT state for possible additional data to come in before it actually closes. In the case above, netstat showed the UDP socket never closed until the application was closed even if I waited 30+ minutes.
If you're using a wrapper around winsock like the .NET framework, I've also read some features like setting up async callbacks can leave a UDP socket bound open if you don't clean up the callbacks correctly, but I don't think there are any such features in the win32 winsock API that can cause that.
Just close it. There's nothing in UDP that says that pending data will be sent, unlike TCP.