IPCConnectedFactoryExchange / CFX

Apache License 2.0
79 stars 71 forks source link

Cannot get the send receive to work. #77

Open tomekj320 opened 4 years ago

tomekj320 commented 4 years ago

I've been fighting with this issue for a little while now so hopefully, somebody here can help me. I've tried following the tutorial available on the connectedfactory but I must be doing something wrong.

Here is what I have: Send: ` private void send(object sender, RoutedEventArgs e) { AmqpCFXEndpoint endpoint = new AmqpCFXEndpoint(); endpoint.Open("Vendor1.Model1.Machine34");

        // Encode your username and password into the destination Uri
        string username = "newadmin";
        string password = "s0m3p4ssw0rd";
        string hostname = "192.168.1.52";

        //  eg.  amqps://myusername:mypassword@mycfxbroker.mydomain.com
        Uri uri = new Uri(string.Format("amqps://{0}:{1}@{2}", username, password, hostname));

        // Target exchange on broker (shown here in RabbitMQ compatible format)
        string amqpTarget = "/exchange/CFXExchange";
        endpoint.AddPublishChannel(uri, amqpTarget);

        string targetEndpointHostname = "192.168.1.52";
        string targetCFXHandle = "Vendor2.Model2.Machine55";
        string remoteUri = string.Format("amqp://{0}", targetEndpointHostname);

        // Set a timeout of 20 seconds.  If the target endpoint does not
        // respond in this time, the request will time out.
        AmqpCFXEndpoint.RequestTimeout = TimeSpan.FromSeconds(20);

        // Build a GetEndpointInfomation Request
        CFXEnvelope request = CFXEnvelope.FromCFXMessage(new WhoIsThereRequest()
        {

        });
        request.Target = amqpTarget;
        CFXEnvelope response = endpoint.ExecuteRequest(remoteUri, request);
    }

`

Receive: ` private void open(object sender, RoutedEventArgs e) { AmqpCFXEndpoint endpoint = new AmqpCFXEndpoint(); endpoint.Open("Vendor2.Model2.Machine55");

        // Encode your username and password into the destination Uri
        string username = "newadmin";
        string password = "s0m3p4ssw0rd";
        string hostname = "192.168.1.52";

        //  eg.  amqps://myusername:mypassword@mycfxbroker.mydomain.com
        Uri uri = new Uri(string.Format("amqps://{0}:{1}@{2}", username, password, hostname));

        // Source queue on broker (shown here in RabbitMQ compatible format)
        string amqpSource = "/queue/CFXQueque";
        endpoint.OnRequestReceived += Endpoint_OnRequestReceived;
        endpoint.AddSubscribeChannel(uri, amqpSource);

    }
    private CFXEnvelope Endpoint_OnRequestReceived(CFXEnvelope request)
    {
        // Encode your username and password into the destination Uri
        string username = "newadmin";
        string password = "s0m3p4ssw0rd";
        string hostname = "192.168.1.52";

        //  eg.  amqps://myusername:mypassword@mycfxbroker.mydomain.com
        Uri myRequestUri = new Uri(string.Format("amqps://{0}:{1}@{2}", username, password, hostname));
        string myCFXHandle = "Vendor2.Model2.Machine55";

        // Process request.  Return Result.
        if (request.MessageBody is WhoIsThereRequest)
        {
            CFXEnvelope result = CFXEnvelope.FromCFXMessage(new WhoIsThereResponse()
            { CFXHandle = myCFXHandle, RequestNetworkUri = myRequestUri.ToString(), RequestTargetAddress = "" });
            result.Source = myCFXHandle;
            result.Target = request.Source;
            return result;
        }

        return null;
    }

`

I see the messages are received by the AMQP ( see img ) Capture

Any help would be appreciated

alexisfouqueteuroplacer commented 4 years ago

Hi

I assume you are not receiving the request on your receiving endpoint? Do you see the messages in the queue tab of RabbitMQ as well ? Do you see your receiving endpoint in the connexions tab of RabbitMQ?

I don't see obvious error, except that you don't set any certificate, and when you use https addresses, a certificate is needed by default. Try to do endpoint.ValidateCertificates = false before both endpoint.open(...).

I hope it helps

Alexis

tomekj320 commented 4 years ago

@alexisfouqueteuroplacer Thank you for your respond.

Yes, that is correct I don't receive the message's at the endpoint side. There is something happening in the queue side of things Whenever a send a message a new queue is created with a strange name ( example: amq.gen-FJGpmhs7q9QYuKRfaAhVWw) However, the message is sent to the correct queue ( CFXQueue ). Capture Capture

No, I don't see any connections in the connections tab of CFX.

I've tried your suggestion but sadly it didn't change my situation.

alexisfouqueteuroplacer commented 4 years ago

After a second look I think this line is wrong : request.Target = amqpTarget;

The target here should be the target cfx handle, not the name of the exchange.

tomekj320 commented 4 years ago

@alexisfouqueteuroplacer

I've tried it with both the handle and the name of the exchange , both dont seem to work for me.

QuantaVn commented 4 years ago

Because CFX SDK uses AMQP.Net Lite library, it will open a socket when sending direct Request to an Endpoint. In order to work with Request/Response in the same machine (with the same IP as yours: 192.168.1.52), you need to use different ports. As you can see in my example, when an Endpoint want to send a Request to an MES Simulator, the Endpoint need to know the CFX Handle and Network Uri of the MES Simulator: image And here is my code to send Request:

        private async Task RunAsyncRequest()
        {
            // Send Request/Reponse pattern command, and ensure response
            CFXEnvelope req = new CFXEnvelope(new AreYouThereRequest() { CFXHandle = txtMESHandle.Text });
            req.Source = endpoint.CFXHandle;
            req.Target = txtMESHandle.Text;
            CFXEnvelope resp = await endpoint.ExecuteRequestAsync(txtMESUri.Text, req);
            AddToResults($"REQUEST SENT:\n {req.ToJson(true)}");
            if (resp != null)
            {
                AddToResults($"RESPONSE RECEIVED:\n {resp.ToJson(true)}");
            }
        }

(Note: amqp://localhost:5672 is the default Uri of RabbitMQ installed in my laptop)

tomekj320 commented 4 years ago

@QuantaVn Thank you for your response.

I'm not quite sure how to achieve the connection perhaps you can explain this a bit more. My situation is not fully localhost based. I have the AMQP server running on a different pc ( 192.168.1.52:5672 ) and both the sender and receiver are running on my own laptop ( 192.168.1.44 ).

Recieve: ` AmqpCFXEndpoint endpoint = new AmqpCFXEndpoint();

        myRequestUri = new Uri(string.Format("amqp://{0}", "192.168.1.44:54243"));

        endpoint.OnConnectionEvent += Endpoint_OnConnectionEvent;
        endpoint.Open("Vendor2.Model2.Machine55", myRequestUri);

        // Encode your username and password into the destination Uri
        string username = "newadmin";
        string password = "s0m3p4ssw0rd";
        string hostname = "192.168.1.52:5672";

        //  eg.  amqps://myusername:mypassword@mycfxbroker.mydomain.com
        Uri uri = new Uri(string.Format("amqp://{0}:{1}@{2}", username, password, hostname));

        // Source queue on broker (shown here in RabbitMQ compatible format)
        string amqpSource = "/queue/CFXQueque";
        endpoint.OnRequestReceived += Endpoint_OnRequestReceived;
        endpoint.AddSubscribeChannel(uri, amqpSource);

`

Send: ` endpoint.OnConnectionEvent += Endpoint_OnConnectionEvent; Uri myRequestUri = new Uri(string.Format("amqp://{0}", "192.168.1.44:54244")); endpoint.Open("Vendor1.Model1.Machine34", myRequestUri);

        // Encode your username and password into the destination Uri
        string username = "newadmin";
        string password = "s0m3p4ssw0rd";
        string hostname = "192.168.1.52.5672";

        //  eg.  amqps://myusername:mypassword@mycfxbroker.mydomain.com
        Uri uri = new Uri(string.Format("amqp://{0}:{1}@{2}", username, password, hostname));

        // Target exchange on broker (shown here in RabbitMQ compatible format)
        string amqpTarget = "/exchange/CFXExchange";
        endpoint.AddPublishChannel(uri, amqpTarget);

`

So after implementing your suggestion, I have this. But I'm noticing 2 things.

  1. Receive do's connect to the AMQP server but is shown in the connection tab with a completely different port that is set during opening.
  2. Send never trigger's the connection event.
simon-smith commented 4 years ago

Hi If you are still having issues the attached code might help you out. This is my CFX Client test program. It listens to the RabbitMQ and reads messages and displays them. Also are you sure that your RabbitMQ is correctly configured? It is not uncommon for the setup to be tricky to get right. There is a document on the IPC-CFX website explaining the setup. https://cfx.ipc.org/files/IPC-CFX-AMQP-Guide-v1_0.pdf CFXClient.zip

I hope this helps. Simon

QuantaVn commented 4 years ago

@tomekj320 : Actually, as I mentioned, because CFX SDK using AMQP.Net Lite library, the RabbitMQ doesn't have any role in the direct communication between your Receiver and Sender. RabbitMQ has responsibility only for Publish/Subscribe communication. (You can try comment out the AddPublishChannel() and AddSubscribeChannel() for testing direct communication) The Receiver opens its host and port and waits for incoming Requests. The Sender must know the Receiver's host & port to send Requests. That's all.

HaythemLtifi commented 3 years ago

same probelm, it create a new queue of its own. any idea on how to fix this please?

image