Now, I trying to send the real-time data from MQL4. Into the socket server build by Python-Flask
My MQL4 using socket-library-mt4-mt5.mqh. But i don't how to handle the event to the socket.
My socket server
from flask import Flask, render_template
from flask_socketio import SocketIO
app = Flask(__name__)
socketio = SocketIO(app)
#app.route('/')
def sessions():
return render_template('index.html')
def messageReceived(methods=['GET', 'POST']):
print('message was received!!!')
#socketio.on('my event')
def handle_my_custom_event(json, methods=['GET', 'POST']):
print('received my event: ' + str(json))
socketio.emit('my response', json, callback = messageReceived)
My MQL4 code, As Socket client
#define SOCKET_LIBRARY_USE_EVENTS
#include <socket-library-mt4-mt5.mqh>
string Hostname = "127.0.0.1";
ushort ServerPort = "5000";
ClientSocket * glbClientSocket = NULL;
int OnInit()
{
return NULL;
}
void OnDeinit(const int reason)
{
if (glbClientSocket) {
delete glbClientSocket;
glbClientSocket = NULL;
}
}
void OnTick()
{
if (!glbClientSocket) {
glbClientSocket = new ClientSocket(Hostname, ServerPort);
if (glbClientSocket.IsSocketConnected()) {
Print("Client connection succeeded");
} else {
Print("Client connection failed");
}
}
if (glbClientSocket.IsSocketConnected()) {
string strMsg = Symbol() + "," + DoubleToString(SymbolInfoDouble(Symbol(), SYMBOL_BID), 6) + "," + DoubleToString(SymbolInfoDouble(Symbol(), SYMBOL_ASK), 6) + " Hello from MQL \n";
glbClientSocket.Send(strMsg);
} else {
}
if (!glbClientSocket.IsSocketConnected()) {
// Destroy the server socket. A new connection
// will be attempted on the next tick
Print("Client disconnected. Will retry.");
delete glbClientSocket;
glbClientSocket = NULL;
}
}
And i check The connection it's work, But still wrong the method
As you see the my MQL4 code it's doesn't have the handle event function
127.0.0.1 - - [2019-08-29 13:25:36] "AUDUSD,0.672250,0.672360 Hello from MQL" 400 - 0.000403
<socket fileno=10 sock=127.0.0.1:5000 peer=127.0.0.1:37348>: Invalid HTTP method: 'AUDUSD,0.672260,0.672360 Hello from MQL \n'
The question is how to handle event like socket.on('my event') in javascript. Into my MQL4 code.
Related
This is the error rising, could you please tell how shall I solve this issue?
I have unity side which is server and there is a server. There is also python side client, I just try to change the color of the sphere using control commands from python side
matlab/_controlUR_ver2/socket_client.py", line 9, in sendRandomColors
s.connect(('192.168.43.18', 1755))
TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
This is the python client:
import socket
import random
from time import sleep
def sendRandomColors():
s = socket.socket()
# connect to the server on local computer
s.connect(('192.168.43.18', 1755))
s.send((
str(random.randint(0,255)) + ","+
str(random.randint(0,255)) + ","+
str(random.randint(0,255)) + ","+
str(random.randint(0,255))).encode())
s.close()
for i in range(100):
sendRandomColors()
sleep(1)
and This is the c# server on unity:
using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
public class ChangeColor : MonoBehaviour
{
static Socket listener;
private CancellationTokenSource source;
public ManualResetEvent allDone;
public Renderer objectRenderer;
private Color matColor;
public static readonly int PORT = 1755;
public static readonly int WAITTIME = 1;
ChangeColor()
{
source = new CancellationTokenSource();
allDone = new ManualResetEvent(false);
}
// Start is called before the first frame update
async void Start()
{
objectRenderer = GetComponent<Renderer>();
await Task.Run(() => ListenEvents(source.Token));
}
// Update is called once per frame
void Update()
{
objectRenderer.material.color = matColor;
}
private void ListenEvents(CancellationToken token)
{
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, PORT);
listener = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(localEndPoint);
listener.Listen(10);
while (!token.IsCancellationRequested)
{
allDone.Reset();
print("Waiting for a connection... host :" + ipAddress.MapToIPv4().ToString() + " port : " + PORT);
listener.BeginAccept(new AsyncCallback(AcceptCallback),listener);
while(!token.IsCancellationRequested)
{
if (allDone.WaitOne(WAITTIME))
{
break;
}
}
}
}
catch (Exception e)
{
print(e.ToString());
}
}
void AcceptCallback(IAsyncResult ar)
{
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
allDone.Set();
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
void ReadCallback(IAsyncResult ar)
{
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
int read = handler.EndReceive(ar);
if (read > 0)
{
state.colorCode.Append(Encoding.ASCII.GetString(state.buffer, 0, read));
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
else
{
if (state.colorCode.Length > 1)
{
string content = state.colorCode.ToString();
print($"Read {content.Length} bytes from socket.\n Data : {content}");
SetColors(content);
}
handler.Close();
}
}
//Set color to the Material
private void SetColors (string data)
{
string[] colors = data.Split(',');
matColor = new Color()
{
r = float.Parse(colors[0]) / 255.0f,
g = float.Parse(colors[1]) / 255.0f,
b = float.Parse(colors[2]) / 255.0f,
a = float.Parse(colors[3]) / 255.0f
};
}
private void OnDestroy()
{
source.Cancel();
}
public class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
public StringBuilder colorCode = new StringBuilder();
}
}
Code:
const WebSocket = require('ws');
const shaUtil = require('js-sha256');
String.prototype.hashCode = function() {
return shaUtil(String(this));
};
const server = new WebSocket.Server({port:2909}); // Change to another port if you like.
// Hashes of client keys. Generate them using getHash.js and place them here.
const passes = {
'86cec081a5288000ddb804c24ac70de62a5060e5b4f4068b01a01f9f29dddacc': 0, // Receiver's key.
'c01223ad2ba8cdd184ded788cf6d3469111229cbe6cb3939ce24f471e8f257ca': 1, // Buzzer #1's key.
'5476be1700a54be0572b0066b32b5905986641fa163c5eabd52369eb3a2685cf': 2 // Buzzer #2's key...
};
var receiver = null;
var senders = {1: null, 2: null, 3: null, 4: null}; // You can add more/remove buzzers if you want to.
const lockClients = true; // If it is true, a connected client will not be overriden by another client logging in until it disconnects.
if (lockClients) canConnect = function(id) {
if (id == 0) return receiver === null;
return senders[id] === null;
}
else canConnect = function(id) {
return true;
}
function processBuzzer(client) {
if (receiver == null) return;
receiver.send('BUZZER '+client.buzzerId);
//console.log('Buzzer #'+client.buzzerId+' is activated.');
}
function onDisconnect(id) {
if (id === 0) {
receiver = null;
console.log('Receiver has disconnected.');
} else {
senders[id] = null;
console.log('Sender #' + id + ' has disconnected.');
}
}
server.on('connection', function(client) {
client.sendBuzzer = function() {};
client.on('message', function(message) {
if (message.startsWith('PASSWORD: ')) {
let id = passes[message.substring(10).hashCode()];
if (id !== undefined && canConnect(id)) {
if (client.buzzerId !== undefined) onDisconnect(client.buzzerId);
client.buzzerId = id;
if (id === 0) {
receiver = client;
console.log('Receiver has connected.');
} else {
senders[id] = client;
console.log('Sender #' + id + ' has connected.');
client.sendBuzzer = function() { processBuzzer(this) };
client.send('CONNECTED SUCCESSFULLY');
}
}
}
if (message == 'BUZZER') client.sendBuzzer();
});
client.on('close', function() {
if (client.buzzerId !== undefined) onDisconnect(client.buzzerId);
});
});
console.log('Server is running.');
If i started this with nodeJS with "node server.js", it appears Server is running.....no mistakes.....and now, Iwill connect to this server with the receiver.py (Python-File):
serverAddress = 'ws://192.168.1.50:2909' # The server's address.
clientKey = 'receiver' # The client key corresponding to the receiver's hash.
buzzerSoundFile = 'buzzer.wav' # The name/path of the buzzer sound file.
import asyncio
import websockets
from win32com.client import Dispatch
import winsound
from threading import Thread
app = Dispatch('Powerpoint.Application')
def playBuzzerSound():
global buzzerSoundFile
winsound.PlaySound(buzzerSoundFile, winsound.SND_FILENAME+winsound.SND_ASYNC)
async def mainFunction():
global serverAddress, clientKey
async with websockets.connect(serverAddress) as ws:
await ws.send('PASSWORD: ' + clientKey)
while True:
msg = await ws.recv()
if msg.startswith('BUZZER '):
if app.Run('onBuzzerActivated', int(msg[7:])):
Thread(target=playBuzzerSound).start();
asyncio.get_event_loop().run_until_complete(mainFunction())
I got an error 200 like this:
websockets.exceptions.InvalidStatusCode: server rejected WebSocket connection: HTTP 200
What's wrong ??
I want to send a Json object from Android client to Python server and a response text back to client. But it showing error
A request to send or receive data was disallowed
Server
class ThreadedServer(object):
def __init__(self, host, port):
self.host = host
self.port = port
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind((self.host, self.port))
print("Listening.....")
def listenS(self):
self.sock.listen(5)
while True:
client, address = self.sock.accept()
print("Accepted from :: "+str(address))
threading.Thread(target = self.listenToClientS,args = (client,address)).start()
def listenToClientS(self, client, address):
data = self.sock.recv(1024)
Mydata = json.load(data)
print(Mydata)
if __name__ == "__main__":
ThreadedServer('IP',5000).listenS()
Client
public class client {
private String serverIpAddress = "IP";
private boolean connected = false;
private int serverPort = 5000;
protected void connect() {
if (!connected) {
if (!serverIpAddress.equals("")) {
Thread cThread = new Thread(new ClientThread());
cThread.start();
}
}
}
public class ClientThread implements Runnable {
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
Log.d("ClientActivity", "C: Connecting...");
Socket socket = new Socket(serverIpAddress,serverPort);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
JSONObject json = new JSONObject();
json.put("myData", 23);
String myJsonObjectSerialized = json.toString();
oos.writeObject(myJsonObjectSerialized);
oos.flush();
oos.close();
socket.close();
Log.d("ClientActivity", "C: Closed.");
} catch (Exception e) {
Log.e("ClientActivity", "C: Error", e);
connected = false;
}
}
}
I am working with a chat application with a simple python localhost server, using NSStream to send and recieve data via network socket connection. App just worked fine in the iPhone application, but not getting stream in the mac application.
My Python Server Code
from twisted.internet.protocol import Factory, Protocol
from twisted.internet import reactor
class MacChat(Protocol):
def connectionMade(self):
print "a client connected"
self.factory.clients.append(self)
print "clients are ", self.factory.clients
def connectionLost(self, reason):
self.factory.clients.remove(self)
def dataReceived(self, data):
a = data.split(':')
print a
if len(a) > 1:
command = a[0]
content = a[1]
msg = ""
if command == "iam":
self.name = content
msg = self.name + " has joined"
elif command == "msg":
msg = self.name + ": " + content
print msg
for c in self.factory.clients:
c.message(msg)
def message(self, message):
self.transport.write(message + '\n')
factory = Factory()
factory.clients = []
factory.protocol = MacChat
reactor.listenTCP(80, factory)
print "Mac Chat server started"
reactor.run()
Mac
ChatViewController.h
#import <Cocoa/Cocoa.h>
#interface ChatViewController : NSViewController
#property (strong,nonatomic) NSString *userName;
#end
ChatViewController.m
#import "ChatViewController.h"
#interface ChatViewController ()<NSTableViewDataSource,NSTableViewDelegate,NSStreamDelegate>
{
NSInputStream *inputStream;
NSOutputStream *outputStream;
NSMutableArray * messages;
}
#property (weak) IBOutlet NSButton *btnSend;
#property (weak) IBOutlet NSTextField *txtMessage;
#property (weak) IBOutlet NSTableView *tableview;
#end
#implementation ChatViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do view setup here.
}
-(void)setUserName:(NSString *)userName
{
[self initNetworkCommunication];
NSString *response = [NSString stringWithFormat:#"iam:%#",userName];
NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
[outputStream write:[data bytes] maxLength:[data length]];
messages = [[NSMutableArray alloc] init];
}
- (void)initNetworkCommunication {
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)#"localhost", 80, &readStream, &writeStream);
inputStream = (__bridge_transfer NSInputStream *)readStream;
outputStream = (__bridge NSOutputStream *)writeStream;
inputStream.delegate=self;
outputStream.delegate=self;
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
}
- (IBAction)btnAtnSend:(id)sender {
NSString *response = [NSString stringWithFormat:#"msg:%#", self.txtMessage.stringValue];
NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
[outputStream write:[data bytes] maxLength:[data length]];
self.txtMessage.stringValue = #"";
}
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
// Get a new ViewCell
NSTableCellView *cellView = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];
// Since this is a single-column table view, this would not be necessary.
// But it's a good practice to do it in order by remember it when a table is multicolumn.
if( [tableColumn.identifier isEqualToString:#"cell"] )
{
NSString *s = (NSString *) [messages objectAtIndex:row];
cellView.textField.stringValue = s;
}
return cellView;
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return [messages count];
}
-(CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row
{
return 30;
}
#pragma mark NSStream Delegate
-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
switch (eventCode) {
case NSStreamEventOpenCompleted:
NSLog(#"Stream opened");
break;
case NSStreamEventHasBytesAvailable:
if (aStream == inputStream) {
uint8_t buffer[1024];
int len;
while ([inputStream hasBytesAvailable]) {
len = (int)[inputStream read:buffer maxLength:sizeof(buffer)];
if (len > 0) {
NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
if (nil != output) {
NSLog(#"server said: %#", output);
[self messageReceived:output];
}
}
}
}
break;
case NSStreamEventErrorOccurred:
NSLog(#"Can not connect to the host!");
break;
case NSStreamEventEndEncountered:
{
[aStream close];
[aStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
break;
default:
NSLog(#"Unknown event");
}
}
- (void) messageReceived:(NSString *)message {
[messages addObject:message];
[self.tableview reloadData];
[self.tableview scrollRowToVisible:messages.count-1];
}
#end
OK. Looks like this is based on the example from raywenderlich.com.
The example is flawed, as mentioned by "glyph" in the comments section:
This tutorial makes some incorrect assumptions about how data is delivered to an application from a network.
Read glyph's post before building on this code.
For your particular problem, you've made a lot of changes to the original code. At a glance, it's not clear to me that "setUserName" is ever even called.
Without that, nothing else will happen.
I am using a Node.js server to talk to a python DAO with Amazon SQS. I'm able to send a SQS to the DAO but have no idea on how to send something back on the python DAO and listen for it properly on the Node.js server. I'm also curious how to call another function based off what the Node.js SQS message is received from the python DAO. Any help would be greatly appreciated! Here's my code so far:
Node.js listening for SQS code:
app.get('/readDAOSQSMessage', function(req, res) {
var params = {
QueueUrl: DAO_QUEUE_URL,
MaxNumberOfMessages: 1, // how many messages do we wanna retrieve?
VisibilityTimeout: 60, // seconds - how long we want a lock on this job
WaitTimeSeconds: 3 // seconds - how long should we wait for a message?
};
sqs.receiveMessage(params, function(err, data) {
if (data.Messages) {
var message = data.Messages[0],
body = JSON.parse(message.Body);
res.send("Username: " + body.username + " Password: " + body.password);
removeFromQueue(message, DAO_QUEUE_URL);
}
});
});
Python sending SQS code:
queue = conn.get_queue('DAO-Queue')
writeQueue = conn.get_queue('DaoToServerQueue')
message = RawMessage()
message.set_body("This is my first message.")
writeQueue.write(message)
while True:
rs = queue.get_messages()
if len(rs) > 0:
m = rs[0]
print("Message Body: " + m.get_body())
message = m.get_body()
#unicodedata.normalize('NFKD',message).encode('ascii','ignore')
#command = 'dao.'+message[1:-1]
message = message.encode('ascii','ignore')
print "message: "+message[1:-1]
print "backslash: "+'\\'
replace_str = '\\'+'"'
print replace_str
print message.find(replace_str)
print"\nmessage type: "+str(type(message))
message = message.replace(replace_str,'"')
print "\nnew message: "+message
command = 'dao.'+message[1:-1]
print "\n command: "+command
#unicodedata.normalize('NFDK',message).encode('ascii','ignore')
#command = 'dao.'+ message
#unicodedata.normalize('NFDK',command).encode('ascii','ignore')
eval(command)
print("Command: " + command)
queue.delete_message(m)
Normally you want to listen to messages on the receiving side by long-polling.
function readMessages() {
async.parallel([
pollMessage,
], function(err, callbacks) {
readMessages();
});
}
function pollMessage(callback) {
sqs.receiveMessage({
QueueUrl: receiveQueue,
WaitTimeSeconds: 5,
MaxNumberOfMessages: 1,
// VisibilityTimeout: 20
}, function(err, data) {
if (err) console.log(err);
if (!data) {
callback();
return;
}
if (data.Messages) {
// Get the first message (should be the only one since we said to only get one above)
for (var i = 0; i < data.Messages.length; i++) {
var message = data.Messages[i];
removeFromQueue(message, callback);
// Now this is where you'd do something with this message
handleIncomeMessage(message); // whatever you wanna do
// Clean up after yourself... delete this message from the queue, so it's not executed again
}
} else {
callback();
}
});
}
The code to be executed as lambda function on your NodeJS server.
You can decide what to do with the message by attaching message type to the payload. Notice the handleIncomeMessage() function above, which can be something like:
function handleIncomeMessage(data) {
var msg = JSON.parse(data.Body);
var type = msg.type;
console.log("Got a new sqs message: ", msg.type);
switch (type) {
case 'someCoolType':
{
Manager.proceedWithCoolType(msg.restOfPayload);
break;
}
}
}