Messaging domain - reconnect to queue issue
Laro88
✭
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?
Kind regards
Laro882009-11-15 16:28:16
0
Comments
-
Additional info
This code always tries to create a queue, it throws an exception as expected, and in the catch it grabs the queue using its name.
However, this queue is also only working once after a warmstart
CODE
try
{
ipcQueue_FromRAP = theController.Ipc.CreateQueue("ToPc_"+taskname,5, Ipc.IPC_MAXMSGSIZE);
}
catch(Exception ex)
{
ipcQueue_FromRAP = theController.Ipc.GetQueue("ToPc_"+taskname);
}
0 -
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.
BRCarlos Martinez
ABB0 -
Ok, but how to do that?
The queues created on the pc side throws an exception when attempting to delete them, what is required to delete them ?
How do I delete a queue in RAPID, I haven't found a "RMQDelete" function.
0 -
< ="-" ="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">HelloI 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.
0 -
How will it be possible to use GUIDs as queue names? The Queues created by the PC then have a new name unknown to the tasks in RAPID and vice versa....
In RAPID a simple send might look like this
PROC TX_String(NUM ID, STRING Message)
RMQFindSlot rmqslotThis ,"ToPc_T_ROB1";
RMQSendMessage rmqslotThis, Message, UserDef:=ID;
ENDPROC
where the ToPc_T_ROB1 is the queue created on the PC - it has to be the same all the time since this code is not generated.
The same goes for the connection to the TRAP routine
CONNECT connectnumString WITH RX_T_ROB1;
I simply don't see how GUIDs can be used since they are used since the names must be known in both ends in advance.
Please elaborate on this topic...
Yours sincerely
0 -
Hello
It depends on your app.
If it's request/response then RAPID don't need to know your queue name, it can respond to the caller anyway.
Otherwise could your app send a message to RAPID to tell rapid which queue name shall be use.
An "echo" rapid client.
MODULE RAB_COM
VAR intnum myintnum;
VAR rmqheader myrmqheader;
VAR rmqmessage myrmqmsg;
VAR rmqslot myrabclient;
PROC main()
VAR string mystring;
TPErase;
CONNECT myintnum WITH RABMsgs;
IRMQMessage mystring, myintnum;
WHILE TRUE DO
WaitTime 15;
ENDWHILE
IDelete myintnum;
ENDPROC
TRAP RABMsgs
VAR string recstring;
VAR string client;
VAR num userdef;
VAR rmqslot sender;
RMQGetMessage myrmqmsg;
RMQGetMsgHeader myrmqmsg Header:=myrmqheaderSenderId:=myrabclientUserDef:=userdef;
IF myrmqheader.datatype = "string" THEN
RMQGetMsgData myrmqmsg, recstring;
client:= RMQGetSlotName(myrabclient);
TPWrite "In RABMsgs";
TPWrite "Rec: "+ recstring;
TPWrite "From: " + client;
TPWrite "userdef: " + ValToStr(userdef);
IF userdef <> -1 THEN
RMQSendMessage myrabclient, recstring UserDef:=userdef;
ELSE
RMQSendMessage myrabclient, recstring;
ENDIF
ELSE
TPWrite "Unknown data received in RABMsgs";
ENDIF
ERROR
TEST ERRNO
CASE ERR_RMQ_INVALID:
TPWrite "ERR_RMQ_INVALID error reported";
TRYNEXT;
CASE ERR_RMQ_TIMEOUT:
TPWrite "ERR_RMQ_TIMEOUT error reported";
TRYNEXT;
CASE ERR_RMQ_NAME:
TPWrite "ERR_RMQ_NAME error reported";
TRYNEXT;
CASE ERR_RMQ_MSGSIZE:
TPWrite "ERR_RMQ_MSGSIZE error reported";
TRYNEXT;
CASE ERR_RMQ_FULL:
TPWrite "ERR_RMQ_FULL error reported";
TRYNEXT;
CASE ERR_RMQ_VALUE:
TPWrite "ERR_RMQ_VALUE error reported";
TRYNEXT;
CASE ERR_RMQ_DIM:
TPWrite "ERR_RMQ_DIM error reported";
TRYNEXT;
CASE ERR_RMQ_NOMSG:
TPWrite "ERR_RMQ_NOMSG error reported";
TRYNEXT;
DEFAULT:
TPWrite "ERROR: Unknown error reported"Num:= ERRNO;
Stop;
ENDTEST
ENDTRAP
ENDMODULE
0 -
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.
BR
0 -
I am now sending the queue name ( the queue for the VC to send messages to ) in a message from the PC, it works most of the time.
However the PC SDK is behaving oddly.
The GetQueue("RMQ_T_ROB1") returns a seemingly fine IPC Connection all the time, however, sometimes the queue does not work.
I send a message immediately after the GetQueue, but sometimes it does not come through though. I have no Idea why.
0 -
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.
# Copyright 2003.
#
# Startup.cmd script for 5.0
#
console
startup_log -file $INTERNAL/startup.log
...
0 -
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
0 -
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?
0 -
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.
0
Categories
- All Categories
- 5.5K RobotStudio
- 396 UpFeed
- 18 Tutorials
- 13 RobotApps
- 297 PowerPacs
- 405 RobotStudio S4
- 1.8K Developer Tools
- 249 ScreenMaker
- 2.7K Robot Controller
- 310 IRC5
- 59 OmniCore
- 7 RCS (Realistic Controller Simulation)
- 785 RAPID Programming
- AppStudio
- 3 RobotStudio AR Viewer
- 18 Wizard Easy Programming
- 105 Collaborative Robots
- 4 Job listings