Performance improvements would likely occur at higher load where the persistent connection
of EVAPI would be advantageous over the new TCP connection for every http request.
As far as issues I had with writing an evapi client were things that would be necessary
(in my mind) to make it "production quality". Things like detecting connection
failure, and re-establishing the connection, etc. It was a culmination of little things
outside of my wheelhouse that caused me to pause the dream of having my next external
dependency use evapi.
Kaufman
Senior Voice Engineer
E: bkaufman(a)bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 |
Flowroute Client Support: 855.356.9768
[img]<https://www.sip.us/>
[
img]<https://www.siptrunk.com/>
[
img]<https://www.flowroute.com/>
________________________________
From: Alex Balashov via sr-users <sr-users(a)lists.kamailio.org>
Sent: Thursday, January 9, 2025 8:31 AM
To: Kamailio (SER) - Users Mailing List <sr-users(a)lists.kamailio.org>
Cc: Alex Balashov <abalashov(a)evaristesys.com>
Subject: [SR-Users] Re: evapi not processing received messages
CAUTION: This email originated from outside the organization. Do not click links or open
attachments unless you recognize the sender and know the content is safe.
Given the constraints and requirements previously expressed in this thread, I don't
see much point in using EVAPI for you, nor is there any reason to expect a performance
improvement.
You might keep more of your sanity if you just stick to the async_http_client plan. My
arguments in favour of EVAPI were rooted in a different set of assumptions about what
you're doing and why you're doing it.
-- Alex
On Jan 9, 2025, at 4:21 am, Sergio Charrua via
sr-users <sr-users(a)lists.kamailio.org> wrote:
Hi Ben!
Be my guest :)
It is not async HTTP but you can easily modify the script to support async http using
python's aiohttp module.
Please, if you find in the script something relevant to correct or improve, feel free to
let me know.
import socket
import json
import requests
# Configuration
REMOTE_HOST = 'KANAILIO_IP' # Replace with the remote service's host/IP
REMOTE_PORT = 8888 # Replace with the remote service's port
API_URL = 'THE_URL' # Replace with the actual REST API endpoint
def main():
# Create a TCP socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# Connect to the remote service
client_socket.connect((REMOTE_HOST, REMOTE_PORT))
print(f"Connected to {REMOTE_HOST}:{REMOTE_PORT}")
# Continuously listen for data from the service
while True:
# Receive up to 4 KB of data (adjust buffer size as needed)
data = client_socket.recv(4096)
strData = data.decode('utf-8')
strData = strData.strip().rstrip(',')
# If no data is received, connection is closed or lost
if not data:
print("Connection closed by remote service.")
break
# Attempt to parse the received data as JSON
try:
objJson = json.dumps(
strData.replace("<null>","") )
received_json = json.loads(objJson)
#print("Received JSON from service:", received_json)
# Forward the JSON to the REST API via POST
try:
response = requests.post(API_URL, json=received_json)
# Check for successful status code
print("Response from HTTP : " +
str(response.status_code))
if response.status_code == 200:
# Parse the REST API response as JSON
response_json = str(response.json())
print("Received JSON from REST API:", response_json)
# Send the JSON response back to the remote service
client_socket.sendall((response_json).encode('utf-8'))
print("Sent response back to service.")
else:
# Handle non-200 response
error_msg = {
"error": f"REST API returned status code
{response.status_code}",
"details": response.text
}
client_socket.sendall(json.dumps(error_msg).encode('utf-8'))
except requests.exceptions.RequestException as req_err:
# Handle requests exceptions (network errors, timeouts, etc.)
error_msg = {
"error": "REST API request failed",
"details": str(req_err)
}
client_socket.sendall(json.dumps(error_msg).encode('utf-8'))
print("Exception - Sent error message back to service.")
except json.JSONDecodeError as json_err:
# Handle JSON parsing errors
error_msg = {
"error": "Invalid JSON received",
"details": str(json_err)
}
client_socket.sendall(json.dumps(error_msg).encode('utf-8'))
print("Sent JSON error message back to service.")
except socket.error as sock_err:
print(f"Socket error: {sock_err}")
finally:
# Close the socket connection when done
client_socket.close()
print("Socket closed.")
if __name__ == '__main__':
main()
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
On Wed, Jan 8, 2025 at 11:10 PM Ben Kaufman via sr-users
<sr-users(a)lists.kamailio.org> wrote:
Do you have an example of your python script (or at least a simplified example that
reproduces the problem).
Honestly, I tried going down this path as a follow up to the discussions on using
http-async the other week, and while I have no doubt there is a performance gain using
evapi, I had no success coding an async client (in other words, my client requests to an
http service, etc. were blocking). That's not an indictment of evapi, rather it's
the state of my coding ability in other language. I was able to get a simple synchronous
example working, but if I couldn't get it to perform better than http_async, there was
no gain.
Kaufman
Senior Voice Engineer
E: bkaufman(a)bcmone.com
SIP.US Client Support: 800.566.9810 | SIPTRUNK Client Support: 800.250.6510 |
Flowroute Client Support: 855.356.9768
Regards,
Kaufman
From: Sergio Charrua via sr-users <sr-users(a)lists.kamailio.org>
Sent: Wednesday, January 8, 2025 11:25 AM
To: Kamailio (SER) - Users Mailing List <sr-users(a)lists.kamailio.org>
Cc: Sergio Charrua <sergio.charrua(a)voip.pt>
Subject: [SR-Users] evapi not processing received messages CAUTION: This email
originated from outside the organization. Do not click links or open attachments unless
you recognize the sender and know the content is safe.
Hi all!
I have implemented evapi module on Kamailio 5.8.4, calling a python script.
Python script is listening to a socket. It receives messages (JSON) from Kamailio, makes
an HTTP request somewhere, and sends the response back to Kamailio.
The Python script is working fine: it connects to Kamailio, sends HTTP requests, and
forwards a response back to Kamailio: I have confirmed using TCPDump that, in fact, the
data is received and forwarded back.
However, despite showing messages that the Python client script is correctly connected to
Kamailio, the event_route[evapi:message-received] is never executed.
Probably there is some detail that I am missing, but the docs and online info for evapi
are very rare, and they all show very similar configuration.
And as I wrote, I have confirmed using TCPDump that the data is received from Python
client script to Kamailio node.
What am I missing?
This is my Kamailio cfg:
[loads modules]
[sets modparams]
modparam("evapi","bind_addr","10.20.20.1:8888")
debug=2
children=16
log_facility=LOG_LOCAL0
log_prefix="{$mt $hdr(CSeq) $ci} "
disable_sctp = yes
force_rport = yes
rundir="/tmp"
request_route {
if ( is_method("ACK") ) {
if ( t_check_trans() ) {
t_relay();
}
exit;
}
if(is_method("OPTIONS")){
sl_reply("200", "OK");
exit;
}
if(is_method("CANCEL")){
sl_reply("200","OK");
sl_reply("487","Request Terminated");
exit;
}
route(TOEVAPI);
exit;
}
event_route[evapi:connection-new] {
xlog("LINFO","new connection from
[$evapi(srcaddr):$evapi(srcport)]\n");
if($evapi(srcaddr)!="10.20.0.1") {
evapi_close();
exit;
}
}
event_route[evapi:connection-closed] {
xlog("LINFO","connection closed by
$evapi(srcaddr):$evapi(srcport)\n");
}
event_route[evapi:message-received] {
xlog("LINFO","received [$evapi(msg)] from
$evapi(srcaddr):$evapi(srcport)\n");
jansson_get("t-index", "$evapi(msg)",
"$var(t-index)");
jansson_get("t-label", "$evapi(msg)",
"$var(t-label)");
$var(evmsg) = $evapi(msg);
xlog("L_INFO", "preparing to resume transaction for processing:
$var(tindex) / $var(tlabel)\n");
t_continue("$var(tindex)", "$var(tlabel)",
"EVAPIRESPONSE");
}
route[EVAPIRESPONSE] {
xlog("L_INFO", "resumed transaction for processing: $T(id_index) /
$T(id_label)\n");
[do stuff]
}
route[TOEVAPI]{
xlog("L_INFO", "suspended transaction: $T(id_index) /
$T(id_label)\n");
evapi_async_relay( [some JSON string] );
exit;
}
Thanks in advance!
Atenciosamente / Kind Regards / Cordialement / Un saludo,
Sérgio Charrua
__________________________________________________________
Kamailio - Users Mailing List - Non Commercial Discussions --
sr-users(a)lists.kamailio.org
To unsubscribe send an email to sr-users-leave(a)lists.kamailio.org
Important: keep the mailing list in the recipients, do not reply only to the sender!
__________________________________________________________
Kamailio - Users Mailing List - Non Commercial Discussions --
sr-users(a)lists.kamailio.org
To unsubscribe send an email to sr-users-leave(a)lists.kamailio.org
Important: keep the mailing list in the recipients, do not reply only to the sender!
--
Alex Balashov
Principal Consultant
Evariste Systems LLC
Web:
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fevaristes…
Tel: +1-706-510-6800
__________________________________________________________
Kamailio - Users Mailing List - Non Commercial Discussions --
sr-users(a)lists.kamailio.org
To unsubscribe send an email to sr-users-leave(a)lists.kamailio.org
Important: keep the mailing list in the recipients, do not reply only to the sender!