I have tried but couldn't figure it out on my own.
I know MT4 provides Pipe and WebRequest(), as a means of communication, but WebSocket isn't built as part of the Programming. So for now, Pipe is the only thing available. But communication with Pipe breaks at some point. It skips some signals when sent.
How can I get around this please guys?
How can I get around this please guys ?
Free to use either a ZeroMQ or a nanomsg signalling / messaging framework
having been in such a need many years back, started to use ZeroMQ / MQL4-binding, so as to make MetaTrader Terminal work inside a distributed-computing QuantFX-analytics and ML-based augmented trading system.
No O/S localhost-only pipe, no file-based masquerades, but a fair, distributed, low-latency signalling/messaging, with:
remote keyboard / terminal system-console ( yes, added a DSL command language )
remote centralised logs ( avoids MQL4 execution get blocked from resource contentions )
distributed remote AI/ML-predictive engine, with latency under << 80 [ms] RTT
distributed remote automated trade-management processing
ZeroMQ is a way to go, if integration needs are to be kept under your own design controls. A brief sketch was presented here, in [ ZeroMQ hierarchy in less than a five seconds ] Section.
Feel free to read more posts on this and about the differences between WebSockets and ZeroMQ here, in the zeromq and other related posts.
I tried ZeroMQ but couldn't get it working properly.
I'm using WinSockets now and so far have no problems with it.
See: https://www.mql5.com/en/blogs/post/706665
Here you will find a way to use WinSockets in MQL as a server or as a client or both.
I know links can become dead but there is no way to attach files to this answer and the code does not format properly so I cannot include it.
You can then use any programming language that also supports sockets to communicate with your MQL EA. I'm using the build-in node implementation.
See: https://www.digitalocean.com/community/tutorials/how-to-develop-a-node-js-tcp-server-application-using-pm2-and-nginx-on-ubuntu-16-04
const net = require('net');
const port = 7070;
const host = '127.0.0.1';
const server = net.createServer();
server.listen(port, host, () => {
console.log('TCP Server is running on port ' + port + '.');
});
let sockets = [];
server.on('connection', function(sock) {
console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
sockets.push(sock);
sock.on('data', function(data) {
console.log('DATA ' + sock.remoteAddress + ': ' + data);
// Write the data back to all the connected, the client will receive it as data from the server
sockets.forEach(function(sock, index, array) {
sock.write(sock.remoteAddress + ':' + sock.remotePort + " said " + data + '\n');
});
});
// Add a 'close' event handler to this instance of socket
sock.on('close', function(data) {
let index = sockets.findIndex(function(o) {
return o.remoteAddress === sock.remoteAddress && o.remotePort === sock.remotePort;
})
if (index !== -1) sockets.splice(index, 1);
console.log('CLOSED: ' + sock.remoteAddress + ' ' + sock.remotePort);
});
});
Pipe in MQL is implemented through files, so you can use files instead of pipes - you will receive same or faster result, and no need to care of the communication
Related
In https://github.com/holochain/holochat-rust, how are the files ui/holoclient.js and ui/holoclient.map obtained ?
Also, is there any official documentation about that that I missed and is this still the way to get a UI to talk to the holochain container ?
ui/holoclient.js is a tiny library that makes it much easier to talk to a running Holochain app instance. The current way of connecting your GUI to an instance is a JSON-RPC-like process via a local WebSocket connection. It's intended as a nice wrapper to make zome function calls feel like local, in-browser function calls. Documentation is currently very light, but it shouldn't take much to figure out how it's supposed to work using the example. In a nutshell:
const url = 'ws://localhost:3000/'
window.holoclient.connect(url).then(({call, close}) => {
document.getElementById('form').addEventListener('submit', e => {
e.preventDefault()
// First, get a list of locally running Holochain instances...
call('info/instances')().then(info => {
// Now that we have instance info, we can make zome calls into any of them
// by referring to them by DNA hash (and agent ID) as specified in our
// container config.
// Search for the instance we're looking for, given known DNA and agent
// hashes.
const matchingInstances = Object.entries(info)
.find(([id, value]) => value.dna === 'blog_dna_hash' && value.agent === 'my_agent_hash')
const instance = getInstance(info, 'the_dna_hash', 'the_agent_hash')
const content = document.querySelector('#message').value
// Make another zome call now
call(instance, 'blog', 'main', 'create_post')({
content: content
})
})
})
})
It's written in TypeScript, which would mean that ui/holoclient.map is a 'source map', a file which maps line numbers in the compiled JavaScript file to line numbers in the original TypeScript source. Both Chrome and Firefox look for and use those source maps when you're debugging your JS.
In Python I have the option of using a "poller" object which polls blocking sockets for messages waiting and unblocks after a specified number of milliseconds (in the case below, 1000, in the while True block):
import zmq
# now open up all the sockets
context = zmq.Context()
outsub = context.socket(zmq.SUB)
outsub.bind("tcp://" + myip + ":" + str(args.outsubport))
outsub.setsockopt(zmq.SUBSCRIBE, b"")
inreq = context.socket(zmq.ROUTER)
inreq.bind("tcp://" + myip + ":" + str(args.inreqport))
outref = context.socket(zmq.ROUTER)
outref.bind("tcp://" + myip + ":" + str(args.outrefport))
req = context.socket(zmq.ROUTER)
req.bind("tcp://" + myip + ":" + str(args.reqport))
repub = context.socket(zmq.PUB)
repub.bind("tcp://" + myip + ":" + str(args.repubport))
# sort out the poller
poller = zmq.Poller()
poller.register(inreq, zmq.POLLIN)
poller.register(outsub, zmq.POLLIN)
poller.register(outref, zmq.POLLIN)
poller.register(req, zmq.POLLIN)
# UDP socket setup for broadcasting this server's address
cs = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
cs.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
cs.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
# housekeeping variables
pulsecheck = datetime.utcnow() + timedelta(seconds = 1)
alivelist = dict()
pulsetimeout = 5
while True:
polls = dict(poller.poll(1000))
if inreq in polls:
msg = inreq.recv_multipart()
if msg[1] == b"pulse": # handle pluse
ansi("cyan", False, textout = " pulse" + "-" + msg[0].decode())
if not msg[0] in alivelist.keys():
handlechange(msg[0])
alivelist[msg[0]] = datetime.utcnow() + timedelta(seconds = pulsetimeout)
if outsub in polls:
msgin = outsub.recv_multipart()[0]
repub.send(msgin) # republish
msg = unpacker(msgin)
if isinstance(msg, dict):
valu = msg.get("value")
print(".", end = "", flush = True)
else:
ansi("green", False, textout = msg)
if req in polls:
msg = req.recv_multipart()
valmsg = validate_request(msg)
if not valmsg[0]:
ansi("red", True); print(valmsg[1]); ansi()
elif len(alivelist) > 0:
targetnode = random.choice(list(alivelist.keys()))
inreq.send_multipart([targetnode, packer(valmsg[1])])
ansi("blue", True, textout = "sent to " + targetnode.decode())
else:
ansi("red", True, textout = "NO CONNECTED NODES TO SEND REQUEST TO")
if outref in polls:
msg = outref.recv_multipart()
destinataire, correlid = msg[1].split(b"/")
req.send_multipart([destinataire, correlid, msg[2]])
I want to implement something analogous in Elixir (or Erlang) but my preferred native library, chumak, doesn't seem to implement polling. How do I implement non-blocking receives in Erlang/Elixir, preferably using Chumak, but I'll move to another Erlang zeroMQ library if necessary? My socket pattern preference is router sends, dealer receives.
EDIT
My use case is the following. I have a third party financial service which serves data based on requests, with answers coming asynchronously. So you can send multiple requests, and you'll get responses back after an unspecified period of time, and not necessarily in the same order you sent them.
So I need to connect this service into Erlang (actually Elixir) and ZeroMQ seems like a good fit. Multiple users connected (via Phoenix) to Erlang/Elixir will send requests, and I need to pass these on to this service.
The problem comes if there is an error in one of the requests, or the third party service has some kind of problem. I will be blocking-waiting for a response, and then unable to service new requests from Phoenix.
Basically I want to listen constantly for new requests, send them over, but if one request doesn't produce a response, I will have one-fewer responses than requests and that will lead to an eternal wait.
I understand that if I send requests separately, then the good ones will produce responses so I don't need to worry about blocking even if, over time, I get quite a big numerical difference between requests sent and responses received. Maybe the design idea is that I shouldn't worry about this? Or should I try to track one-for-one responses to requests and timeout the non-responses somehow? Is this a valid design pattern?
Is your system constantly connected to the asynchronous query resource, or are you making a new connection with each query?
Each situation has its own natural model in Erlang.
The case of: A single (or pool of) long-term connection(s)
Long-term connections that maintain a session with the resource (the way a connection with a database would work) are most naturally modelled as processes within your system that have the sole job of representing that external resource.
The requirements of that process are:
Translate the external resource's messages into internally meaningful messages (not just passing junk through -- don't let raw, external data invade your system unless it is totally opaque to you)
Keep track of timed out requests (and this may require something sort of like polling, but can be done more precisely with erlang:send_after/3
This implies, of course, that the module that implements this process will need to speak the protocol of that resource. But if this is accomplished then there really isn't any need for a messaging broker like an MQ application.
This allows you to have that process be reactive and block on receive while the rest of your program goes off to do whatever its doing to do. Without some arbitrary polling that will surely run you into the Evil Black Swamp of Scheduling Issues.
The case of: A new connection per query
If each query to the resource requires a new connection the model is similar, but in here you spawn a new process per query and it represents the query itself within your system. It blocks waiting for the response (on a timeout), and nothing else matters to it.
That is the easier model, actually, because then you don't have to scrub a list of past, possibly timed out requests that will never return, don't have to interact with a set of staged timeout messages sent via erlang:send_after/3, and you move your abstraction one step closer to the actual model of your problem.
You don't know when these queries will return, and that causes some potential confusion -- so modeling each actual query as a living thing is an optimal way to cut through the logical clutter.
Either way, model the problem naturally: As a concurrent, asynch system
In no case, however, do you want to actually do polling the way you would in Python or C or whatever. This is a concurrent problem, so modelling it as such will provide you a lot more logical freedom and is more likely to result in a correct solution that lacks corners that give rise to weird cases.
I can't get why my browser console shows an error from time to time. As I can see this error doesn't break anything.
media.twiliocdn.com/sdk/rtc/js/ip-messaging/releases/0.10.6/twilio-ip-messaging.js:22423
WebSocket is already in CLOSING or CLOSED state.
Also I noticed that after some time of inactivity in chat window, I get 'messageAdded' event with a huge latency (it's take around 5+ seconds after message was sent), but Typing event works fine. Why is this happens?
Closed socket errors indicate an issue with the local network and Chrome - can you confirm if you are going through a proxy? Could you also test using Firefox if possible?
If not, can you uncheck "automatically detect settings" in the network part of the Chrome Settings? Clear the cache and then update to the latest version and try again.
As far as the messageAdded event is concerned, what does your code look like?
Adding event listeners for IP Messaging:
//set up listeners for events for the active channel
activeChannel.on('messageAdded', addMessageToHistory);
And the messageAdded method I've seen used without issue:
function addMessageToHistory(message) {
console.log('Message added, adding a message to the history, sid:' + message.sid);
//get a handle to the chat history wrapper
var $messageHistory = $('#chat-history');
//process the message elements
var $messageEntry = $('<div id="' + message.sid + '" class="chat-message clearfix"/>');
var $messageContent = $('<div class="chat-message-content clearfix"/>');
var $messageTime = $('<span id="time_' + message.sid + '" class="chat-time"/>').text(formatDate(message.timestamp));
var $messageAuthor = $('<h5/>').text(message.author);
var $messageBody = $('<p id="msgbody_" ' + message.sid + '" />').text(message.body);
var $messageSeparator = $('<hr/>');
//build the message content
$messageTime.appendTo($messageContent);
$messageAuthor.appendTo($messageContent);
$messageBody.appendTo($messageContent);
//build the message entry
$messageContent.appendTo($messageEntry);
$messageSeparator.appendTo($messageEntry);
//ad the message entry to the history
$messageEntry.appendTo($messageHistory);
//scroll to end
$messageHistory.scrollTop($('#chat-history')[0].scrollHeight);
activeChannel.updateLastConsumedMessageIndex(message.index);
}
If your problem persists, then I'd suggest you contact support where we can take a closer look.
The examples in the RxJS README seem to suggest we have to subscribe to a source. In other words: we wait for the source to send events. In that sense, sources seem to be push-based: the source decides when it creates new items.
This contrasts, however, with iterators, where strictly speaking new items need only be created when requested, i.e., when a call is made to next(). This is pull-based behavior, also known as lazy generation.
For instance, a stream could return all Wikipedia pages for prime numbers. The items are only generated when you ask for them, because generating all of them upfront is quite an investment, and maybe only 2 or 3 of them might be read anyway.
Can RxJS also have such pull-based behavior, so that new items are only generated when you ask for them?
The page on backpressure seems to indicate that this is not possible yet.
Short answer is no.
RxJS is designed for reactive applications so as you already mentioned if you need pull-based semantics you should be using an Iterator instead of an Observable. Observables are designed to be the push-based counterparts to the iterator, so they really occupy different spaces algorithmically speaking.
Obviously, I can't say this will never happen, because that is something the community will decide. But as far as I know 1) the semantics for this case just aren't that good and 2) this runs counter to the idea of reacting to data.
A pretty good synopsis can be found here. It is for Rx.Net but the concepts are similarly applicable to RxJS.
Controlled observable from the page you referenced can change a push observable to pull.
var controlled = source.controlled();
// this callback will only be invoked after controlled.request()
controlled.subscribe(n => {
log("controlled: " + n);
// do some work, then signal for next value
setTimeout(() => controlled.request(1), 2500);
});
controlled.request(1);
A truly synchronous iterator is not possible, as it would block when the source was not emitting.
In the snippet below, the controlled subscriber only gets a single item when it signals, and it does not skip any values.
var output = document.getElementById("output");
var log = function(str) {
output.value += "\n" + str;
output.scrollTop = output.scrollHeight;
};
var source = Rx.Observable.timer(0, 1000);
source.subscribe(n => log("source: " + n));
var controlled = source.controlled();
// this callback will only be invoked after controlled.request()
controlled.subscribe(n => {
log("controlled: " + n);
// do some work, then signal for next value
setTimeout(() => controlled.request(1), 2500);
});
controlled.request(1);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/2.5.2/rx.all.js"></script>
<body>
<textarea id="output" style="width:150px; height: 150px"></textarea>
</body>
I'm quite late to the party, but it's actually very simple to combine generators with observables. You can pull a value from a generator function by syncing it with a source observable:
const fib = fibonacci()
interval(500).pipe(
map(() => fib.next())
)
.subscribe(console.log)
Generator implementation for reference:
function* fibonacci() {
let v1 = 1
let v2 = 1
while (true) {
const res = v1
v1 = v2
v2 = v1 + res
yield res
}
}
I am building an MVC application that includes an asynchronous image upload so each image, once uploaded, calls the action. Image uploading can be cpu intensive and require time so we are trying to avoid in-action processing.
I have read about using async actions, but we are also processing images at other times, so we have opted to handle image processing through a console application.
What is the proper method for calling a console application from an MVC action asynchronously? Basically we just want to pass the console app some parameters, and tell it start without waiting for any kind of response from the console.
Our program file is an exe.
Speed is our main concern here.
Thanks so much for your help!
EDIT
As per Brian's suggestion here is what we added:
Process pcx = new System.Diagnostics.Process();
ProcessStartInfo pcix = new System.Diagnostics.ProcessStartInfo();
pcix.FileName = "C:\\utils_bin\\fileWebManager\\ppWebFileManager.exe";
pcix.Arguments = WrkGalId.ToString() + " " + websiteId.ToString() + "" + " " + "19" + " \"" + dFileName + "\" ";
pcix.UseShellExecute = false;
pcix.WindowStyle = ProcessWindowStyle.Hidden;
pcx.StartInfo = pcix;
pcx.Start();
You would use Process.Start to execute an external application, e.g.:
Process.Start(#"C:\\path\to\my\application.exe");