;This is a simple HTTP server that can receive and return data. ;Can be used for example to launch QM macros from other computers and smartphones. ;Below is instructions how to send commands from an Android mobile device with Tasker.
;On your Android device install Tasker app. It is for sending HTTP requests. Costs $2.99. Or find a free app that can send HTTP requests. ;In Tasker create new task and add action HTTP Post. ;;;Set field Server:Port, like 192.168.8.123:5033. As Server, use one of IP addresses that you can see in QM Options -> Network. The 5033 is server's port that is used in this macro, see below. ;;;Set field Data / File. Can be any text or variable or file. At first just for testing. ;;;Set field Content Type, like text/plain. ;;;Optionally set field Output File, like Documents/test1.txt. Only if you want to receive some data from QM.
;Run this function and in the dialog click button Start. ;Run the Tasker task. ;;;In QM output you should see Tasker's HTTP POST request that includes data at the end. ;;;If was set Output File, the task creates the file. It contains text DATA.
if(getopt(nthreads)>1)ret;;allow single instance #compile"__TcpSocket"
Thank you both Gintaras for the wonderful HTTP Server Dialog to receive input from Tasker (android device) and Ron for the nitty gritty details in setting up the connection with tasker within QM app.
I'm looking forward to seeing more examples on this topic like:
- Sending image/file/audio/video from PC/Laptop to Android machine and vice versa.
- Activate/run an app in android phone by using QM on PC/Laptop and vice versa.
Using the above parameters: The response speed is too slow, but The received data is always complete, the response speed is still very slow even when testing locally.
I have been stuck on this issue for a few days. Thanks for Any suggestions or help!
_____________________________________________________________The incomplete returned data is as follows:
POST /saveFile HTTP/1.1
Accept: application/json,text/html,application/xhtml+xml,application/xml,text/*;q=0.9, image/*;q=0.8, */*;q=0.7
Content-Type: multipart/form-data; boundary=--------------------------493891244813812906191617
content-length: 1831226
User-Agent: axios/1.7.4
Accept-Encoding: gzip, compress, deflate, br
Host: 127.0.0.1:5032
Connection: keep-alive
iVBORw0KGgoAAAANSUhEUgAABAAAAAQACAIAAADwf7zUAAEAAE..............(The data is truncated in the middle, and there is no ending line similar to the red text shown below. )
_____________________________________________________________The complete returned data is as follows:
;Test file(Pic.png) size is 1342KB; file(Doc.docx) size is 525KB
;The response speed is very fast, but The data reception is unstable, sometimes complete and sometimes incomplete.
client.Receive(_s 2048000)
;The response speed is too slow, but The received data is always complete, the response speed is still very slow even when testing locally. ;client.Receive(_s 0)
Much work to create a HTTP server using TCP. At first need to learn how HTTP protocol works. Your server code must parse HTTP headers eg Content-Length to know how much data to read. Then call Receive until all data is read.
12-12-2024, 07:14 AM (This post was last modified: 12-12-2024, 07:29 AM by Davider.)
Thanks for your suggestion.
Is it possible to first retrieve a small amount of data, such as the first 300 bytes, and then extract the value of `Content-Length: XXXX` from it? Finally, retrieve the full data based on the size specified by that value?
I don’t understand the specific implementation details and am unsure how to modify the code in the existing TcpSocket class.
Don't need to modify TcpSocket class. It's a low-level class, because TCP is a low-level protocol. Use it's functions to create higher-level code, for example a HTTP server.
Don't need GET. When client.Receive receives the first data, it probably contains all HTTP headers, including Content-Length (example below). If possibly there is more data to read, it probably returns 1. But it does not know how much data the client will send. It can return 1 even if there is no more data. The caller must somehow determine whether need to read again (and again...). For it can be used Content-Length. This should work in simple cases.
12-12-2024, 10:21 AM (This post was last modified: 12-12-2024, 10:22 AM by Davider.)
Using the above code, sending a POST request from local PowerShell works successfully.
However, on a remote server, using FRP to create port forwarding and executing the same PowerShell POST request from the remote server, the data received locally is still incomplete.
In any case, the code below is always able to receive the complete data, but the response is very slow.
;Reads HTTP message. ;Returns: 1 if OK, 0 if failed.
;method - receives the HTTP method string, like "GET" or "POST". ;path - receives the request target, like "/" or "/file.html". ;headers - receives the request headers. Raw. ;body - if used, receives the request body. For example the POST data. Raw.
;REMARKS ;If body data is sent, the request headers should contain Content-Length. Data must not be chunked or compressed.
str s int dataStart flags ;g1 int r =Receive(s 81000 flags) if(r=2)goto gserverError ;;timeout
dataStart=find(s "[][]") if(dataStart<0) ,if(r=0)goto gBadRequest ,flags=1 ,goto g1 ;;wait for complete headers
dataStart+4
12-12-2024, 01:05 PM (This post was last modified: 12-12-2024, 09:24 PM by Davider.)
Thanks again.
I am testing POST requests locally in PowerShell and the open-source workflow automation software n8n, but I am still encountering some instability.