Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have created a class that extends TcpLink and is instantiated in a custom Kismet Sequence Action. It is being instantiated correctly and is making the GET HTTP request that I need it to (I have checked my access log in apache) and Apache is responding to the request with the appropriate content.

The problem I have is that I'm using the event receive mode and it appears that somehow the handler for the Opened event is halted after a specific number of lines of code have executed.

Here is my code for the Opened event:

event Opened()
{
    // A connection was established
    WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] event opened");
    WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] Sending simple HTTP query");

    //The HTTP GET request
    //char(13) and char(10) are carrage returns and new lines
    requesttext = "userId="$userId$"&apartmentId="$apartmentId;

    SendText("GET /"$path$"?"$requesttext$" HTTP/1.0");
    SendText(chr(13)$chr(10));
    SendText("Host: "$TargetHost);
    SendText(chr(13)$chr(10));
    SendText("Connection: Close");
    SendText(chr(13)$chr(10)$chr(13)$chr(10));

    //WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] Sent request: "$requesttext);

    //WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] end HTTP query");

    //WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] LinkState: "$LinkState);
    //WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] LinkMode: "$LinkMode);
    WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] ReceiveMode: "$ReceiveMode);
    WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] Error: "$string(GetLastError()));
}

As you can see, a number of the Broadcast calls have been commented out. Initially, only the lines up to the Broadcast containing "[DNomad_TcpLinkClient] Sent request: " were being executed and none of the Broadcasts were commented out. After commenting out that line, the next Broadcast was successful and so on and so forth.

As a test, I commented out the very first Broadcast to see if the connection closing had any effect:

    // A connection was established
    //WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] event opened");
    WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] Sending simple HTTP query");

Upon doing that, an additional Broadcast at the end of the function executed. Thus the inference that there is an upper limit to the number of lines executed.

Additionally, my ReceivedText handler is never called, despite Apache returning the correct HTTP 200 response with a body.

My working hypothesis is that somehow after the Sequence Action finishes executing the garbage collector cleans up the TcpLinkClient instance. My biggest source of confusion with that is how on earth it does it during the execution of an event handler.

Has anyone ever seen anything like this before? My full TcpLinkClient class is below:

/*
 * TcpLinkClient based on an example usage of the TcpLink class by Michiel 'elmuerte' Hendriks for Epic Games, Inc.
 * 
 */ 

class DNomad_TcpLinkClient extends TcpLink;

var PlayerController PC;
var string TargetHost;
var int TargetPort;
var string path;
var string requesttext;
var string userId;
var string apartmentId;
var string statusCode;
var string responseData;

event PostBeginPlay()
{
    super.PostBeginPlay();
}

function DoTcpLinkRequest(string uid, string id) //removes having to send a host
{
    userId = uid;
    apartmentId = id;
    Resolve(targethost);
}

function string GetStatus() {
    return statusCode;
}

event Resolved( IpAddr Addr )
{
    // The hostname was resolved succefully
    WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] "$TargetHost$" resolved to "$ IpAddrToString(Addr));

    // Make sure the correct remote port is set, resolving doesn't set
    // the port value of the IpAddr structure
    Addr.Port = TargetPort;

    //dont comment out this log because it rungs the function bindport
    WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] Bound to port: "$ BindPort() );
    if (!Open(Addr))
    {
        WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] Open failed");
    }
}

event ResolveFailed()
{
    WorldInfo.Game.Broadcast(self, "[TcpLinkClient] Unable to resolve "$TargetHost);
    // You could retry resolving here if you have an alternative
    // remote host.

    //send failed message to scaleform UI
    //JunHud(JunPlayerController(PC).myHUD).JunMovie.CallSetHTML("Failed");
}

event Opened()
{
    // A connection was established
    //WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] event opened");
    WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] Sending simple HTTP query");

    //The HTTP GET request
    //char(13) and char(10) are carrage returns and new lines
    requesttext = "userId="$userId$"&apartmentId="$apartmentId;

    SendText("GET /"$path$"?"$requesttext$" HTTP/1.0");
    SendText(chr(13)$chr(10));
    SendText("Host: "$TargetHost);
    SendText(chr(13)$chr(10));
    SendText("Connection: Close");
    SendText(chr(13)$chr(10)$chr(13)$chr(10));

    //WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] Sent request: "$requesttext);

    //WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] end HTTP query");

    //WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] LinkState: "$LinkState);
    //WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] LinkMode: "$LinkMode);
    WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] ReceiveMode: "$ReceiveMode);
    WorldInfo.Game.Broadcast(self, "[DNomad_TcpLinkClient] Error: "$string(GetLastError()));
}

event Closed()
{
    // In this case the remote client should have automatically closed
    // the connection, because we requested it in the HTTP request.

    WorldInfo.Game.Broadcast(self, "Connection closed.");

    // After the connection was closed we could establish a new
    // connection using the same TcpLink instance.
}

event ReceivedText( string Text )
{   
    WorldInfo.Game.Broadcast(self, "Received Text: "$Text);

    //we dont want the header info, so we split the string after two new lines
    Text = Split(Text, chr(13)$chr(10)$chr(13)$chr(10), true);

    WorldInfo.Game.Broadcast(self, "Split Text: "$Text);

    statusCode = Text;
}

event ReceivedLine( string Line ) {
    WorldInfo.Game.Broadcast(self, "Received Line: "$Line);
}

event ReceivedBinary( int Count, byte B[255] ) {
    WorldInfo.Game.Broadcast(self, "Received Binary of length: "$Count);
}

defaultproperties
{
    TargetHost="127.0.0.1"
    TargetPort=80 //default for HTTP
    LinkMode=MODE_Text
    ReceiveMode=RMODE_Event
    path = "dnomad/datafeed.php"
    userId = "0";
    apartmentId = "0";
    statusCode = "";
    send = false;
}
share|improve this question
    
Are you sure its not a behavior/limitation of Broadcast? What if you write to the console instead? Just taking a shot in the dark here. –  SpartanDonut Oct 22 '12 at 21:46
    
And what a shot in the dark it was. Can you go ahead and post that as an answer so that I can properly reward you @ToddersLegrande? –  Dan Cowell Oct 22 '12 at 22:15
    
Lucky guess. Answer added :) –  SpartanDonut Oct 23 '12 at 5:05

1 Answer 1

While I'd be very happy for someone else to come and give a more specific reason as I don't really have the facts to back up my claim, but it looks like this is a limitation of Broadcast. Alternatively you can write to the console or maybe update some UI elements depending on how you want to handle your messages.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.