Classic Client, RoleTailored Client and MSMQ
aynaluna
Member Posts: 5
For the following Situation:
In Table 18 Customer
Trigger OnModify:
(...)
FMXIntegrationManagement.CreateMessage(Customer);
(...)
Where:
CreateMessage(Customer : Record Customer)
InitNavComCom();
IF NOT XMLPORT.EXPORT(XMLPORT::ACCMOD,OutS,Customer) THEN BEGIN
MESSAGE(Text002,XMLPORT::ACCMOD);
END;
IF NOT OutMsg.Send(0) THEN BEGIN
MESSAGE(Text003,XMLPORT::ACCMOD)
END;
Where :
InitNavComCom()
IF ISCLEAR(MQBus) AND ISCLEAR(CC2) THEN BEGIN
IF ISSERVICETIER THEN BEGIN
IF (NOT CREATE(MQBus,TRUE,TRUE)) OR (NOT CREATE(CC2,TRUE,TRUE)) THEN BEGIN
ERROR(Text001);
END;
END ELSE BEGIN
IF (NOT CREATE(MQBus,TRUE)) OR (NOT CREATE(CC2,TRUE)) THEN BEGIN
ERROR(Text001);
END;
END;
END;
CC2.AddBusAdapter(MQBus,1);
CompanyInformation.GET;
MQBus.OpenWriteQueue(CompanyInformation."FMX Trigger Queue Name",0,0);
OutMsg := CC2.CreateoutMessage('Message [url=queue://'+CompanyInformation]queue://'+CompanyInformation[/url]. Trigger Queue Name");
OutS := OutMsg.GetStream();
Variables:
Name DataType Subtype
MQBus Automation 'Navision MS-Message Queue BusAdapter'.MSMQBusAdapter
CC2 Automation 'Navision Communication Component version 2'.CommunicationComponent
OutMsg Automation 'Navision Communication Component version 2'.OutMessage
OutS OutStream
CompanyInformation Record Company Information
In Classic Client, results are as expected: modifying a Customer creates a Message.
But In RoleTailored Client, when pressing OK button after modfying a Customer record, the error:
"The Server net.[url=tcp://localhost:7046/DynamicsNAV/Service]tcp://localhost:7046/DynamicsNAV/Service[/url] is either unavailable or oyur connection has been lost. Do you want to attempt to reconnect?"
When choosing yes or no, the following error occurs: "The connection to the servers has been lost. The application will close."
Investigating a litle bit further, Computer Management -> System Tools -> Event Viewer -> Windows Logs-> Application, found the following error:
Service: MicrosoftDynamicsNavServer
User: aluna
Type: System.InvalidCastException
Message: Unable to cast object of type 'Microsoft.Dynamics.Nav.Runtime.NavAutomation' to type 'Microsoft.Dynamics.Nav.Runtime.NavStream'.
StackTrace:
at Microsoft.Dynamics.Nav.Runtime.NavAutomation.InvokeMethod[T](String methodName, Object[] arguments)
at Microsoft.Dynamics.Nav.BusinessApplication.Codeunit50002.InitNavComCom()
at Microsoft.Dynamics.Nav.BusinessApplication.Codeunit50002.CreateMessageACCMOD(INavRecordHandle customer)
at Microsoft.Dynamics.Nav.BusinessApplication.Codeunit50002.OnInvoke(Int32 memberId, Object[] args)
at Microsoft.Dynamics.Nav.Runtime.NavApplicationObjectBase.Invoke(Int32 methodId, Object[] arguments)
at Microsoft.Dynamics.Nav.BusinessApplication.Record18.OnModify()
at Microsoft.Dynamics.Nav.Runtime.NavRecord.Modify(DataError errorLevel, Boolean runApplicationTrigger, Boolean runGlobalTrigger)
at Microsoft.Dynamics.Nav.Service.NsDataAccess.Modify(DataError errorLevel, Boolean runApplicationTrigger)
at Microsoft.Dynamics.Nav.Service.NsFormDataAccess.Modify(DataError errorLevel, Boolean runTrigger)
at Microsoft.Dynamics.Nav.Service.NSRecord.Modify(NavConnection con)
at Microsoft.Dynamics.Nav.Service.NSService.<>c__DisplayClass2b.<ModifyRecord>b__2a(Connection connection)
at Microsoft.Dynamics.Nav.Service.NSService.ExecuteOperation[T](String operationName, ServiceOperation`1 operation, Connection connection, Boolean revertLanguageChanges, WindowsIdentity impersonationIdentity)
Source: Microsoft.Dynamics.Nav.Ncl
we think this exception is caused in InitNavComCom, Line OutS := OutMsg.GetStream();
Any ideas on how to resolve it? Help would be really apreciated.
In Table 18 Customer
Trigger OnModify:
(...)
FMXIntegrationManagement.CreateMessage(Customer);
(...)
Where:
CreateMessage(Customer : Record Customer)
InitNavComCom();
IF NOT XMLPORT.EXPORT(XMLPORT::ACCMOD,OutS,Customer) THEN BEGIN
MESSAGE(Text002,XMLPORT::ACCMOD);
END;
IF NOT OutMsg.Send(0) THEN BEGIN
MESSAGE(Text003,XMLPORT::ACCMOD)
END;
Where :
InitNavComCom()
IF ISCLEAR(MQBus) AND ISCLEAR(CC2) THEN BEGIN
IF ISSERVICETIER THEN BEGIN
IF (NOT CREATE(MQBus,TRUE,TRUE)) OR (NOT CREATE(CC2,TRUE,TRUE)) THEN BEGIN
ERROR(Text001);
END;
END ELSE BEGIN
IF (NOT CREATE(MQBus,TRUE)) OR (NOT CREATE(CC2,TRUE)) THEN BEGIN
ERROR(Text001);
END;
END;
END;
CC2.AddBusAdapter(MQBus,1);
CompanyInformation.GET;
MQBus.OpenWriteQueue(CompanyInformation."FMX Trigger Queue Name",0,0);
OutMsg := CC2.CreateoutMessage('Message [url=queue://'+CompanyInformation]queue://'+CompanyInformation[/url]. Trigger Queue Name");
OutS := OutMsg.GetStream();
Variables:
Name DataType Subtype
MQBus Automation 'Navision MS-Message Queue BusAdapter'.MSMQBusAdapter
CC2 Automation 'Navision Communication Component version 2'.CommunicationComponent
OutMsg Automation 'Navision Communication Component version 2'.OutMessage
OutS OutStream
CompanyInformation Record Company Information
In Classic Client, results are as expected: modifying a Customer creates a Message.
But In RoleTailored Client, when pressing OK button after modfying a Customer record, the error:
"The Server net.[url=tcp://localhost:7046/DynamicsNAV/Service]tcp://localhost:7046/DynamicsNAV/Service[/url] is either unavailable or oyur connection has been lost. Do you want to attempt to reconnect?"
When choosing yes or no, the following error occurs: "The connection to the servers has been lost. The application will close."
Investigating a litle bit further, Computer Management -> System Tools -> Event Viewer -> Windows Logs-> Application, found the following error:
Service: MicrosoftDynamicsNavServer
User: aluna
Type: System.InvalidCastException
Message: Unable to cast object of type 'Microsoft.Dynamics.Nav.Runtime.NavAutomation' to type 'Microsoft.Dynamics.Nav.Runtime.NavStream'.
StackTrace:
at Microsoft.Dynamics.Nav.Runtime.NavAutomation.InvokeMethod[T](String methodName, Object[] arguments)
at Microsoft.Dynamics.Nav.BusinessApplication.Codeunit50002.InitNavComCom()
at Microsoft.Dynamics.Nav.BusinessApplication.Codeunit50002.CreateMessageACCMOD(INavRecordHandle customer)
at Microsoft.Dynamics.Nav.BusinessApplication.Codeunit50002.OnInvoke(Int32 memberId, Object[] args)
at Microsoft.Dynamics.Nav.Runtime.NavApplicationObjectBase.Invoke(Int32 methodId, Object[] arguments)
at Microsoft.Dynamics.Nav.BusinessApplication.Record18.OnModify()
at Microsoft.Dynamics.Nav.Runtime.NavRecord.Modify(DataError errorLevel, Boolean runApplicationTrigger, Boolean runGlobalTrigger)
at Microsoft.Dynamics.Nav.Service.NsDataAccess.Modify(DataError errorLevel, Boolean runApplicationTrigger)
at Microsoft.Dynamics.Nav.Service.NsFormDataAccess.Modify(DataError errorLevel, Boolean runTrigger)
at Microsoft.Dynamics.Nav.Service.NSRecord.Modify(NavConnection con)
at Microsoft.Dynamics.Nav.Service.NSService.<>c__DisplayClass2b.<ModifyRecord>b__2a(Connection connection)
at Microsoft.Dynamics.Nav.Service.NSService.ExecuteOperation[T](String operationName, ServiceOperation`1 operation, Connection connection, Boolean revertLanguageChanges, WindowsIdentity impersonationIdentity)
Source: Microsoft.Dynamics.Nav.Ncl
we think this exception is caused in InitNavComCom, Line OutS := OutMsg.GetStream();
Any ideas on how to resolve it? Help would be really apreciated.
0
Comments
-
You're creating the automation objects on the client machine not the server. This means that the stream variable will have to be remoted through the connection between the service tier and the RTC I don't think this is allowed.
It'd be easiest if you can create the automation objects on the server. If you actually need to send the message from the client I think you're going to have to write your own COM object or addin.Robert de Bath
TVision Technology Ltd0 -
I did tried creating the automation in the server (CREATE(AUTOMAT,TRUE,FALSE) and CREATE(AUTOMAT,FALSE,FALSE))
And still errors, but with: The call to member Send failed. there is insufficent memory to perform the operation on the stream0 -
Hmmm, perhaps; are you trying to send a message of more the 4 megabytes?
MSMQ has a 4MB limit on the size of the message and XML is very verbose. (Do you hate XML yet!
)
Then there's these: http://blogs.msdn.com/johnbreakwell/arc ... -away.aspx
One important point though; does the Classic client still work when you run it on the server, the things above probably only apply if it fails too. If not, dunno, sorry.Robert de Bath
TVision Technology Ltd0 -
The XML is definitly smaller than 4 MB (is a small tiny file of 2KB ;-P )
Fortunally all the samples i had display definitly work just fine on Classic Client, unfortunally this all comes crashing into pieces as soon as testing with the RCT.
So it must be something in the way RCT (with the NAS web service and NAS service) is running, been different of the classic client, and is what makes the difference.
any way that succesfully sends messages to a qeueu from navision using MSMQ components (using RCT) could do....
any ideas?0 -
I think you should move code concerning communication with MSMQ and other related "stuff" to be executed by NAS or other schedulers.
Then you do not delay or disturb the user - and you only need to have correct OCX, Automations and so on on the NAS server.
I've found this is very much easier to support and test.
You need to build a "communications log" or other that holds the jobs to be executed - but actually it is quite easy and makes the system very smooth to test for heavy traffic, response time and other..
Best regards and happy coding!Regards,
Henrik Frederiksen, Denmark0 -
Hello everyone.
Thank you very much for your opinions and helps. They were all taked in consideration and very helpful.
After lots or research and trying to use MSMQ in many different ways (inlcuding with the NAS) we have decided to use instead a directory with xml files.
It looks like a few solutions are viable and work on the classic, but not in the RCT.
But again, thank you all for you help.
Cheers
Ayna0 -
OOps, forgot, I was going to try this on the RTC first. Nevermind, I've only tried this on Classic but as it only uses pretty basic automation techniques it should work fine. Though you may need to replace the ScriptControl OCX with the DLL alternative. That is 'Microsoft Script Control 1.0'.ScriptControl
OBJECT Codeunit 90027 MSMQPost No DLL { OBJECT-PROPERTIES { Date=04/11/09; Time=22:12:19; Modified=Yes; Version List=; } PROPERTIES { OnRun=VAR I@1000000000 : Integer; starttime@1000000001 : DateTime; BEGIN MSMQInit('Direct=OS:.\Private$\dump'); starttime := CURRENTDATETIME; FOR I := 1 TO 1000 DO Test; MESSAGE('RunTime = %1', CURRENTDATETIME - starttime); END; } CODE { VAR TestNo@1000000001 : Integer; MSMQInfo@1000000003 : Automation "{D7D6E071-DCCD-11D0-AA4B-0060970DEBAE} 3.0:{D7D6E07C-DCCD-11D0-AA4B-0060970DEBAE}:'Microsoft Message Queue 3.0 Object Library'.MSMQQueueInfo"; MSMQueue@1000000002 : Automation "{D7D6E071-DCCD-11D0-AA4B-0060970DEBAE} 3.0:{D7D6E079-DCCD-11D0-AA4B-0060970DEBAE}:'Microsoft Message Queue 3.0 Object Library'.MSMQQueue"; RUNPostMSMQ@1000000000 : OCX "{0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC}:'ScriptControl Object'"; PROCEDURE MSMQInit@1000000001(FormatName@1000000000 : Text[80]); BEGIN CREATE(MSMQInfo); MSMQInfo.FormatName := FormatName; MSMQueue := MSMQInfo.Open(2, 0); // MQ_SEND_ACCESS, MQ_DENY_NONE END; PROCEDURE MSMQPost@1000000003(VAR XML@1000000000 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v3.0'.DOMDocument";MessageID@1000000001 : Text[30]); VAR MSMQMsg@1000000002 : Automation "{D7D6E071-DCCD-11D0-AA4B-0060970DEBAE} 3.0:{D7D6E075-DCCD-11D0-AA4B-0060970DEBAE}:'Microsoft Message Queue 3.0 Object Library'.MSMQMessage"; BEGIN CREATE(MSMQMsg); RUNPostMSMQ.Language('VBScript'); RUNPostMSMQ.Reset; RUNPostMSMQ.AddObject('XMLin', XML); RUNPostMSMQ.AddObject('MSMQMsg', MSMQMsg); MSMQMsg.Label := MessageID; MSMQMsg.Delivery := 1; // MQMSG_DELIVERY_RECOVERABLE -- Reliable MSMQMsg.Priority := 2; // A little below normal MSMQMsg.Journal := 1; // MQMSG_DEADLETTER -- Don't lose them RUNPostMSMQ.ExecuteStatement('MSMqMsg.body = XMLin.xml'); MSMQMsg.Send(MSMQueue); END; PROCEDURE Test@1000000005(); VAR XML1@1000000000 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 3.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v3.0'.DOMDocument"; BEGIN CREATE(XML1); TestNo += 1; XML1.loadXML('<XML> TEST' + FORMAT(TestNo) + '</XML>'); MSMQPost(XML1, 'Test1'); END; BEGIN END. } }Robert de Bath
TVision Technology Ltd0 -
Hello All
Has anyone had success in sending xml messages from the RTC to msmq?
Using the same objects, I can send a message to msmq when in the classic client. I have paused the queue and confirmed this works. A messages goes in.
When you try to run this in the RTC, I encounter the message that someone posted above:
"The call to member send failed. There is insufficient memory to perform the operation on the stream"
I have debugged this and all passes through seemingly well until I call the .Send() function for automation variable Navision Communication Component Version 2.OutMessage. This is in a codeunit which I obviously call also in the classic client without problems.
I have downloaded a hotfix and this didnt work. Also tried disabling the journals on the message queues, no luck. Changed the service account to admin, restarted no luck.
Can this be achieved in the RTC or is this a case of re-writing with webservices?
Thanks alot
Dave0 -
I did test my bit of code above on the RTC afterwards, it seems that the OCX will only run on the client side so you do have to substitute it with the Automation. Once you've done that it happily dumps messages into the queue. (Server side)
So it looks like the MS Bus DLLs are bust.Robert de Bath
TVision Technology Ltd0 -
Thanks for the reply Robert.
I am using 'Navision Communication Component version 2'.OutMessage which is already an automation type variable - we encounter the error when we call the send function.
The other automation variables we use are 'Navision MS-Message Queue Bus Adapter'.MSMQBusAdapter and also the 'Microsoft XML, v3.0'.DOMDocument
As you found, a tricky one this to decide whether to try to keep going to get it to work in rtc, especially as it all works in classic or to try another approach.0 -
Hello everybody,
I am glad that I found this thread, because I have a similar problem. I already get this to work when I create the file on the server, but I get an error message while creating it on a client. I suggest that there is a problem adressing the queue. Could you give me an example how you adressed it? This would be really helpful!
Thanks in advance!
Greetz
NicoleProTAKT Projekte & Business Software AG
Microsoft Dynamics NAV Partner
Bad Nauheim, Germany
http://www.protakt.de
http://twitter.com/protakt0 -
Hi
Built the Message Queue stuff in CLASSIC and blam, all fails in RTC. grrr
Using code from RASHEDhttp://mibuso.com/blogs/ara3n/2011/04/02/integrating-with-msms-using-dotnet-data-types-in-nav-2009-r2/-
Name DataType Subtype Length
xmlDom DotNet 'System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlDocument
Q DotNet 'System.Messaging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.System.Messaging.MessageQueue
QActiveXFormatter DotNet 'System.Messaging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.System.Messaging.ActiveXMessageFormatter
TempGUID GUID
RTCTempFileName Text 250
SendItem(p_item : Record Item)//SEND TO SCRIBE VM - INTEGRATION Q := Q.MessageQueue('FormatName:Direct=OS:INTEGRATION\PRIVATE$\ScribeIn'); //(use .\PRIVATE$\ for localhost) TempGUID := CREATEGUID; RTCTempFileName := TEMPORARYPATH + '\' + COPYSTR(FORMAT(TempGUID),2,STRLEN(FORMAT(TempGUID))-2) +'.xml'; //3tier file management TextFile.CREATE(RTCTempFileName); TextFile.CREATEOUTSTREAM(OutStr); ProductXMLPort.SetVariables(p_item."No.",p_item.Description,p_item."Base Unit of Measure", p_item."Unit Price",p_item.Blocked,p_item."Gen. Prod. Posting Group",0); ProductXMLPort.SETDESTINATION(OutStr); ProductXMLPort.EXPORT; TextFile.CLOSE; xmlDom := xmlDom.XmlDocument; xmlDom.Load(RTCTempFileName); Q.Formatter := QActiveXFormatter.ActiveXMessageFormatter; Q.Send(xmlDom.InnerXml, 'NAV Label'); CLEAR(xmlDom);
Successfully sent a XML to the Message Queue on another VM via RTC.
<?xml version="1.0" standalone="no" ?>
- <Products ScribeObject="Product" ScribeOperation="Update" ScribeLabel="Product" Label="NAVProductToCRM" MessageLabel="NAVProductToCRM">
- <Product>
<No.>A05</No.>
<Description>ARIZONA 5</Description>
<Base_Unit_of_Measure>EA</Base_Unit_of_Measure>
<Unit_Price>0</Unit_Price>
<Blocked>No</Blocked>
<Gen_Prod_Posting_Group>SYSTEMS</Gen_Prod_Posting_Group>
<Type>0</Type>
</Product>
</Products>
Hope this helps0
Categories
- All Categories
- 75 General
- 75 Announcements
- 66.7K Microsoft Dynamics NAV
- 18.8K NAV Three Tier
- 38.4K NAV/Navision Classic Client
- 3.6K Navision Attain
- 2.4K Navision Financials
- 116 Navision DOS
- 851 Navision e-Commerce
- 1K NAV Tips & Tricks
- 772 NAV Dutch speaking only
- 610 NAV Courses, Exams & Certification
- 1.9K Microsoft Dynamics-Other
- 1.5K Dynamics AX
- 251 Dynamics CRM
- 103 Dynamics GP
- 6 Dynamics SL
- 1.5K Other
- 991 SQL General
- 383 SQL Performance
- 34 SQL Tips & Tricks
- 28 Design Patterns (General & Best Practices)
- Architectural Patterns
- 9 Design Patterns
- 4 Implementation Patterns
- 53 3rd Party Products, Services & Events
- 1.6K General
- 1K General Chat
- 1.6K Website
- 77 Testing
- 1.2K Download section
- 23 How Tos section
- 249 Feedback
- 12 NAV TechDays 2013 Sessions
- 13 NAV TechDays 2012 Sessions