Here is a snippet of code from a C# windows app:
////////////////////////////////
//LINE 0 ( check if the queue allready exists )
if(theController.Ipc.Exists(“ToPc_”+taskname) == false)
{
//LINE 1
ipcQueue_FromRAP = theController.Ipc.CreateQueue(“ToPc_”+taskname,5,Ipc.IPC_MAXMSGSIZE);
}
//LINE 2
ipcQueue_FromRAP = theController.Ipc.GetQueue(“ToPc_”+taskname);
////////////////////////////////
Problem description:
Line 0 (&1) is only running 1. time after a warmstart of the virtual controller. Then it does not execute ( ever ) when the windows app is stopped and started.
Line 2 always runs through so everything seems fine from the PC point of view.
However - events are only received when Line 1 has executed. Line 2 results on a “silent” queue - which I find a bit troublesome…
So - what have I missed / is it a “feature” in the messaging domain to require warmstarts?
The IPC queues in the controller must be deleted by their creators. Make sure that your application destroy the queue before exiting or crashing. This will guarantee that next time, you will be able to create the new queue.
< =“-” =“text/; =utf-8”>< name=“ProgId” =“Word.”>< name=“Generator” =“Microsoft Word 11”>< name=“Originator” =“Microsoft Word 11”> < =“-” =“text/; =utf-8”>< name=“ProgId” =“Word.”>< name=“Generator” =“Microsoft Word 11”>< name=“Originator” =“Microsoft Word 11”>
Hello
I will try to explain how distributed IPC works.
IPC is a local mechanism to send and receive messages between threads on the robot controller. To make it possible for a RAB client to send and receive IPC messages have a thread on the controller been created, dipcts. Dipcts can create/delete ipc queues on behalf of RAB. Dipcts also dispatch all inbound and outbound IPC messages to to/from RAB clients.
For each IPC queue that RAB clients creates in the robot controller is a proxy queue created in the RobotCommunicationRuntime RobController dll. When a message is sent from RAPID to a RAB client queue on the robot controller, the message is read from the real IPC queue and dispatched by dipcts to the host address from which the slot was created and put into the proxy queue in RobController.dll.
When a RAB client calls Receive it reads messages from the proxy queue. When a client deletes a queue is both the proxy queue and the ?oreal?_ IPC queue on the controller deleted. (You can see which IPC queue?_Ts exist on the controller by using the command ipc_show() in the VC/RC console).
When the connection between the client and controller is broken is the IPC queue on the controller deleted and the proxy in the robcontroller.dll is deleted.
When RAB tries to delete a queue and there is no proxy an error is returned and no delete message is sent to the controller. This might be one of your problems with delete, when you restart the RAB application does not the proxy exists anymore but depending on timing it might still exist on the controller. You may also get some problems with this when you debug your application, the robcontroller.dll is might not be unloaded and the queues might or might not be deleted if the tcp connection is timed out or not on the controller.
My recommendation is; when you start your RAB application create a new IPC queue with a new unique name. When you get disconnected and re-connected again try to delete the old and then create a new IPC queue with another new unique name. It is possible to use a GUID as queue name. And run your RAB application in a MTA, at least the thread that calls IPC.
You cannot delete RAPID queues. You cannot delete queues created by other clients.
I was a little bit fast in my response. You can always use the SenderId in RMQSendMessage, not only for request response. You don’t need to know the queue name in RAPID if you have received a message from the pc client. If you have the SenderId you can make as many send you need to the pc client. When the client disconnect, will RAPID get an error on send and must then wait for a new message from the client before it can start to send again.
Is it rapid or is it pc sdk that don’t get a message?
Does it come through if you send another one?
Can you type in the console
ipc_show()
after the message have not come through?
I don’t know which tool you are using but to get a console for the VC,
add console in top of the file
~System<your_system>INTERNALstartup.cmd and make a warmstart
snip startup.cmd
Property of ABB Vasteras/Sweden. All rights reserved.
The problem occurs when connecting using IPC to a Task that has just been started.
There is a log snippet in the end of this post.
The first log entry shows me that my code has established to connection to the messaging domain on the task T_ROB1 without problems. The Task T_ROB1 was started with any Thread.Sleep.
The second entry originates from deep down the PC SDK.
Here is the oddest part, event though I get the error the message sometimes comes through - but I can’t see any pattern in the “sometimes” behaviour. I have tried loading the CPU, but it does not seem to have any affect.
The problem dissapears if I have a sleep of say 400 ms between the thread start and the IPC connection establishment process.
The good news is that when using a guid as a name to create the VC->PC IPC channel ( sending the name to the VC using IPC on the PC->VC channel) it is possible to “clean up” properly, that is - delete the code using this line of C#
theController.Ipc.DeleteQueue(theController.Ipc.GetQueueId(queueguidname_topc));
LOG Dump
2010-01-11 09:51:14,544 [IPC_TaskSystem] DEBUG {ABB Messaging T:TaskSystem} Rap->pc queue e39b9848-2629-4172-adb0-cee9569a4e40 was created
2010-01-11 09:51:14,607 [IPC_TaskSystem] WARN {ABB Messaging T:TaskSystem} Failure while sending messages
System.NullReferenceException: Objektreferencen er ikke indstillet til en forekomst af et objekt.
ved ABB.Robotics.Controllers.SDKBase.UpdateCallContext(Controller controller)
ved ABB.Robotics.Controllers.SDKBase.UpdateCallContext(IController controller)
ved ABB.Robotics.Controllers.Messaging.IpcQueue.Send(Int32 Sender, Int32 Cmd, Int32 UserDef, Int32 UserData, Byte Data)
ved ABB.Robotics.Controllers.Messaging.IpcQueue.Send(IpcMessage Message)
ved Strecon.Rap.Robot.Abb.MessagingThreadSystem.Run() i c:CSPROJEKTERRAP.NETRobotAbbAbbMessagingThreadSystem.cs:linje 139
There must be some timing which I don’t understand. You should be able to send to the rapid task without starting it until the rmq is full.
Does it work after this error?
It is some sort of timing issue on the virtual controller, my real IRC5 behaves nicely. I have left the delay in the code to maintain compatibility with the virtual controller.
Things are currently behaving fine, however I have to do some monitoring on the real IRC5 to see if I have “dead” queues hanging.