From 2c72651dcf748d6940e0faaa6ab6f3a5f6d0231e Mon Sep 17 00:00:00 2001 From: Denis Tereshkin Date: Sun, 14 Nov 2021 15:47:29 +0700 Subject: [PATCH] Initial commit --- qtis.lua | 219 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 qtis.lua diff --git a/qtis.lua b/qtis.lua new file mode 100644 index 0000000..7cb9ae0 --- /dev/null +++ b/qtis.lua @@ -0,0 +1,219 @@ +local alien = require("alien") +json = require "JSON" +date = require "date" +require "string" +struct = require "alien.struct" + +w32sleep = alien.kernel32.Sleep +w32sleep:types { ret = "void", abi = "stdcall", "int" } + + +zmq_pollitem = alien.defstruct { + {"socket", "pointer"}, + {"fd", "int"}, + {"events", "short"}, + {"revents", "short"} +} + +zmq_ctx_new = alien.libzmq.zmq_ctx_new +zmq_ctx_new:types { ret = "pointer", abi="stdcall" } + +zmq_ctx_term = alien.libzmq.zmq_ctx_term +zmq_ctx_term:types { ret = "int", abi="stdcall", "pointer" } + +zmq_bind = alien.libzmq.zmq_bind +zmq_bind:types { ret = "int", abi="stdcall", "pointer", "string" } + +zmq_close = alien.libzmq.zmq_close +zmq_close:types { ret = "int", abi="stdcall", "pointer" } + +zmq_disconnect = alien.libzmq.zmq_disconnect +zmq_disconnect:types { ret = "int", abi="stdcall", "pointer", "string" } + +zmq_setsockopt = alien.libzmq.zmq_setsockopt +zmq_setsockopt:types { ret = "int", abi="stdcall", "pointer", "int", "pointer", "int" } + +zmq_errno = alien.libzmq.zmq_errno +zmq_errno:types { ret = "int", abi="stdcall" } + +zmq_msg_close = alien.libzmq.zmq_msg_close +zmq_msg_close:types { ret = "int", abi="stdcall", "pointer" } + +zmq_msg_data = alien.libzmq.zmq_msg_data +zmq_msg_data:types { ret = "pointer", abi="stdcall", "pointer" } + +zmq_msg_get = alien.libzmq.zmq_msg_get +zmq_msg_get:types { ret = "int", abi="stdcall", "pointer", "int" } + +zmq_msg_init_size = alien.libzmq.zmq_msg_init_size +zmq_msg_init_size:types { ret = "int", abi="stdcall", "pointer", "int" } + +zmq_msg_init = alien.libzmq.zmq_msg_init +zmq_msg_init:types { ret = "int", abi="stdcall", "pointer" } + +zmq_msg_more = alien.libzmq.zmq_msg_more +zmq_msg_more:types { ret = "int", abi="stdcall", "pointer" } + +zmq_msg_recv = alien.libzmq.zmq_msg_recv +zmq_msg_recv:types { ret = "int", abi="stdcall", "pointer", "pointer", "int" } + +zmq_msg_send = alien.libzmq.zmq_msg_send +zmq_msg_send:types { ret = "int", abi="stdcall", "pointer", "pointer", "int" } + +zmq_msg_set = alien.libzmq.zmq_msg_set +zmq_msg_set:types { ret = "int", abi="stdcall", "pointer", "int", "int" } + +zmq_msg_size = alien.libzmq.zmq_msg_size +zmq_msg_size:types { ret = "int", abi="stdcall", "pointer" } + +zmq_poll = alien.libzmq.zmq_poll +zmq_poll:types { ret = "int", abi="stdcall", "pointer", "int", "int" } + +zmq_recv = alien.libzmq.zmq_recv +zmq_recv:types { ret = "int", abi="stdcall", "pointer", "pointer", "int", "int"} + +zmq_send = alien.libzmq.zmq_send +zmq_send:types { ret = "int", abi="stdcall", "pointer", "pointer", "int", "int"} + +zmq_socket = alien.libzmq.zmq_socket +zmq_socket:types { ret = "pointer", abi="stdcall", "pointer", "int"} + +zmq_version = alien.libzmq.zmq_version +zmq_version:types { ret = "void", abi="stdcall", "ref int", "ref int", "ref int"} + +zmq_unbind = alien.libzmq.zmq_unbind +zmq_unbind:types { ret = "int", abi="stdcall", "pointer", "string"} + +function zmq_msg_new() + local buf = alien.buffer(64) + return buf +end + +function zmq_msg_as_string(msg) + return alien.tostring(zmq_msg_data(msg), zmq_msg_size(msg)) +end + +ZMQ_PAIR = 0 +ZMQ_PUB = 1 +ZMQ_SUB = 2 +ZMQ_REQ = 3 +ZMQ_REP = 4 +ZMQ_DEALER = 5 +ZMQ_ROUTER = 6 +ZMQ_PULL = 7 +ZMQ_PUSH = 8 +ZMQ_XPUB = 9 +ZMQ_XSUB = 10 +ZMQ_STREAM = 11 + +ZMQ_POLLIN = 1 +ZMQ_POLLOUT = 2 +ZMQ_POLLERR = 4 + +ZMQ_SNDMORE = 2 +ZMQ_LINGER = 17 + +running = true + +function zmq_msg_from_string(str) + local msg = zmq_msg_new() + zmq_msg_init_size(msg, str:len()) + buf = zmq_msg_data(msg) + bsource = alien.buffer(str) + alien.memcpy(buf, bsource, str:len()) + return msg +end + +function zmq_msg_empty() + local msg = zmq_msg_new() + zmq_msg_init(msg) + return msg +end + +function get_data(class, code) + local lot_size = tonumber(getParamEx(class, code, "LOTSIZE").param_value) + local tick_size = tonumber(getParamEx(class, code, "SEC_PRICE_STEP").param_value) + local tick_value = tonumber(getParamEx(class, code, "STEPPRICET").param_value) + local long_name = getParamEx(class, code, "LONGNAME").param_image + + return { ticker = class .. "#" .. code, + lot_size = lot_size, + tick_size = tick_size, + tick_value = tick_value, + long_name = long_name } +end + +function handle_message(msg) + message("Incoming message") + local rq = json:decode(zmq_msg_as_string(msg)) + local class, code = string.match(rq.ticker, "(%w+)#(%w+)") + message("Requested: " .. rq.ticker) + + local data = get_data(class, code) + if data == nil then + message("Error") + return zmq_msg_from_string("ERROR: can't get data: (" .. class .. "/" .. code .. ")" ), zmq_msg_empty() + end + + message("Returning data") + return zmq_msg_from_string("OK"), zmq_msg_from_string(json:encode(data)) +end + +ctx = nil +sock = nil + +function OnStop() + if sock then + zmq_close(sock) + sock = nil + end + if ctx then + zmq_ctx_term(ctx) + ctx = nil + end +end + +function main() + local status, err = pcall(pmain) + if not status then + message("Error: " .. err) + end + OnStop() +end + +function pmain() + ctx = zmq_ctx_new() + sock = zmq_socket(ctx, ZMQ_REP) + local linger = alien.array("int", {0}) + zmq_setsockopt(sock, ZMQ_LINGER, linger.buffer, 4) + local rc = zmq_bind(sock, "tcp://*:5523") + if rc ~= 0 then + message("Bind error: " .. tostring(rc)) + return + end + + while running do + local pi = zmq_pollitem:new() + pi.socket = sock + pi.fd = 0 + pi.events = ZMQ_POLLIN + pi.revents = 0 + + rc = zmq_poll(pi(), 1, 60000) + if rc > 0 and pi.revents == ZMQ_POLLIN then + message("Incoming") + local msg = zmq_msg_new() + zmq_msg_init(msg) + rc = zmq_msg_recv(msg, sock, 0) + if rc == -1 then + running = false + message("rc: " .. tostring(rc) .. "; " .. tostring(zmq_errno())) + else + local outmsg_header, outmsg_data = handle_message(msg) + zmq_msg_send(outmsg_header, sock, ZMQ_SNDMORE) + zmq_msg_send(outmsg_data, sock, 0) + end + zmq_msg_close(msg) + end + end +end