Highlighted

Problem with LocalConnection

Explorer ,
Nov 23, 2018

Copy link to clipboard

Copied

Hey guys, I'm having an odd problem with the LocalConnection class. Short version: My LocalConnection code runs perfectly until it doesn't.

Long version:

I'm launching a game on Steam/Windows soon, and I'm using an AIR 21 application to load a .swf file using HTMLloader, which runs in a captive Flashplayer (correct me if I'm wrong, but I don't think the newer versions of AIR allow a captive Flashplayer? The end user must NOT be required to have the Flash plugin).

I'm running the game this way so I can use AIR's application features like file-creation and ANEs, while still having access to the deprecated Stage-quality settings of Flashplayer. I'm basically porting a browser-game with vector-graphics to Steam.

I've set up a seperate LocalConnection in each direction, from the AIR .swf to the Flashplayer .swf, and vice versa (both using AS3), and I use them to transfer save files both ways, and to unlock achievements on Steam. When the game starts, this works perfectly, for anywhere between a few minutes to several hours (the connection is used regularly). Then attempts to send data from the Flashplayer side just stop working, and any attempts to close and re-create the connection on that side are unsuccessful, until the game is restarted.

From what I understand, the status error message is the same as if the receiver did not exist. But the AIR .swf (the receiver) is very basic, it just loads Flashplayer and waits for commands through LocalConnection - I don't see what could have happened to it.

As far as I can tell I've done everything mentioned in Adobe's documentation - and my LocalConnection code is the same as the examples given. I've limited the domains to "localhost" and "appname", I've made sure the data I'm sending is less than 40kb, and I've got listeners that display errors if data fails to send.

I have no idea what I've done wrong. Everything works correctly at first.

Is there any other LocalConnection limitations I'm not aware of? What could cause a LocalConnection to close unexpectedly?

Could other running applications possibly interfere? What is the best practice for programming a fail-safe?

Can anyone confirm they've used LocalConnection in a similar way without any problems, and therefor there's a problem with my code somewhere else?

I've heard it's possible for LocalConnections to break if the application crashes and the connection stays open until a system restart.

But I don't think that applies here, since my app doesn't need to crash, and a system restart is not required - only my app needs to be restarted for the connection to work again.

Thanks, and sorry for the long post.

maybe share some code?
how do you setup your sender and receiver?
are you listening for asyncError, securityError, etc.?

etc.

you mention "localhost" and "appname" but you should use a connection name starting with an underscore
see LocalConnection.send()

As discussed in the connect() entry, the current superdomain in added to connectionName by default. If you are implementing communication between different domains, you need to define connectionName in both the sending and receiving LocalConnection objects in such a way that the current superdomain is not added to connectionName. You can do this in one of the following two ways:

  • Use an underscore (_) at the beginning of connectionName in both the sending and receiving LocalConnection objects. In the file that contains the receiving object, use LocalConnection.allowDomain() to specify that connections from any domain will be accepted. This implementation lets you store your sending and receiving files in any domain.

  • Include the superdomain in connectionName in the sending LocalConnection object — for example, myDomain.com:myConnectionName. In the receiving object, use LocalConnection.allowDomain() to specify that connections from the specified superdomain will be accepted (in this case, myDomain.com) or that connections from any domain will be accepted.

in short,
receiver.connect( "_name" )

and
sender.send( "_name", "method", "arg1" )

now LocalConnection can be convenient but they use shared memory to communicate the messages (also why there is a limit of 40KB message) and so what you're experiencing could be another process accessing/modifying the same block of shared memory or whatnot, hard to say what it is without some debug, but the point here is that it uses shared memory and memory can be messed up with.

As an alternative (or backup) you could use NetConnection.connect()

with a connection string "rtmfp:" to create a serverless connection

Creates a two-way connection to an application on Flash Media Server or to Flash Remoting, or creates a two-way network endpoint for RTMFP peer-to-peer group communication. To report its status or an error condition, a call to NetConnection.connect() dispatches a netStatus event.

Call NetConnection.connect() to do the following:

  • Pass "null" to play video and mp3 files from a local file system or from a web server.
  • Pass an "http" URL to connect to an application server running Flash Remoting. Use the NetServices class to call functions on and return results from application servers over a NetConnection object. For more information, see the Flash Remoting documentation.
  • Pass an "rtmp/e/s" URL to connect to a Flash Media Server application.
  • Pass an "rtmfp" URL to create a two-way network endpoint for RTMFP client-server, peer-to-peer, and IP multicast communication.
  • Pass the string "rtmfp:" to create a serverless two-way network endpoint for RTMFP IP multicast communication.

see RTMFP FAQ
and Create a client-side serverless RTMFP connection


or see some library like

GitHub - palkan/as3_p2plocal: as3 lib for local p2p connections (serverless rtmfp)

so yeah it may seem a bit overkill but it is easy to setup and it has many advantages

  • no 40KB limits
  • you can send objects (not strings), eg. it uses AMF serialisation/deserialisation
  • it is more reliable, if the connection fails it will be restored etc.
TOPICS
Development

Views

302

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

Problem with LocalConnection

Explorer ,
Nov 23, 2018

Copy link to clipboard

Copied

Hey guys, I'm having an odd problem with the LocalConnection class. Short version: My LocalConnection code runs perfectly until it doesn't.

Long version:

I'm launching a game on Steam/Windows soon, and I'm using an AIR 21 application to load a .swf file using HTMLloader, which runs in a captive Flashplayer (correct me if I'm wrong, but I don't think the newer versions of AIR allow a captive Flashplayer? The end user must NOT be required to have the Flash plugin).

I'm running the game this way so I can use AIR's application features like file-creation and ANEs, while still having access to the deprecated Stage-quality settings of Flashplayer. I'm basically porting a browser-game with vector-graphics to Steam.

I've set up a seperate LocalConnection in each direction, from the AIR .swf to the Flashplayer .swf, and vice versa (both using AS3), and I use them to transfer save files both ways, and to unlock achievements on Steam. When the game starts, this works perfectly, for anywhere between a few minutes to several hours (the connection is used regularly). Then attempts to send data from the Flashplayer side just stop working, and any attempts to close and re-create the connection on that side are unsuccessful, until the game is restarted.

From what I understand, the status error message is the same as if the receiver did not exist. But the AIR .swf (the receiver) is very basic, it just loads Flashplayer and waits for commands through LocalConnection - I don't see what could have happened to it.

As far as I can tell I've done everything mentioned in Adobe's documentation - and my LocalConnection code is the same as the examples given. I've limited the domains to "localhost" and "appname", I've made sure the data I'm sending is less than 40kb, and I've got listeners that display errors if data fails to send.

I have no idea what I've done wrong. Everything works correctly at first.

Is there any other LocalConnection limitations I'm not aware of? What could cause a LocalConnection to close unexpectedly?

Could other running applications possibly interfere? What is the best practice for programming a fail-safe?

Can anyone confirm they've used LocalConnection in a similar way without any problems, and therefor there's a problem with my code somewhere else?

I've heard it's possible for LocalConnections to break if the application crashes and the connection stays open until a system restart.

But I don't think that applies here, since my app doesn't need to crash, and a system restart is not required - only my app needs to be restarted for the connection to work again.

Thanks, and sorry for the long post.

maybe share some code?
how do you setup your sender and receiver?
are you listening for asyncError, securityError, etc.?

etc.

you mention "localhost" and "appname" but you should use a connection name starting with an underscore
see LocalConnection.send()

As discussed in the connect() entry, the current superdomain in added to connectionName by default. If you are implementing communication between different domains, you need to define connectionName in both the sending and receiving LocalConnection objects in such a way that the current superdomain is not added to connectionName. You can do this in one of the following two ways:

  • Use an underscore (_) at the beginning of connectionName in both the sending and receiving LocalConnection objects. In the file that contains the receiving object, use LocalConnection.allowDomain() to specify that connections from any domain will be accepted. This implementation lets you store your sending and receiving files in any domain.

  • Include the superdomain in connectionName in the sending LocalConnection object — for example, myDomain.com:myConnectionName. In the receiving object, use LocalConnection.allowDomain() to specify that connections from the specified superdomain will be accepted (in this case, myDomain.com) or that connections from any domain will be accepted.

in short,
receiver.connect( "_name" )

and
sender.send( "_name", "method", "arg1" )

now LocalConnection can be convenient but they use shared memory to communicate the messages (also why there is a limit of 40KB message) and so what you're experiencing could be another process accessing/modifying the same block of shared memory or whatnot, hard to say what it is without some debug, but the point here is that it uses shared memory and memory can be messed up with.

As an alternative (or backup) you could use NetConnection.connect()

with a connection string "rtmfp:" to create a serverless connection

Creates a two-way connection to an application on Flash Media Server or to Flash Remoting, or creates a two-way network endpoint for RTMFP peer-to-peer group communication. To report its status or an error condition, a call to NetConnection.connect() dispatches a netStatus event.

Call NetConnection.connect() to do the following:

  • Pass "null" to play video and mp3 files from a local file system or from a web server.
  • Pass an "http" URL to connect to an application server running Flash Remoting. Use the NetServices class to call functions on and return results from application servers over a NetConnection object. For more information, see the Flash Remoting documentation.
  • Pass an "rtmp/e/s" URL to connect to a Flash Media Server application.
  • Pass an "rtmfp" URL to create a two-way network endpoint for RTMFP client-server, peer-to-peer, and IP multicast communication.
  • Pass the string "rtmfp:" to create a serverless two-way network endpoint for RTMFP IP multicast communication.

see RTMFP FAQ
and Create a client-side serverless RTMFP connection


or see some library like

GitHub - palkan/as3_p2plocal: as3 lib for local p2p connections (serverless rtmfp)

so yeah it may seem a bit overkill but it is easy to setup and it has many advantages

  • no 40KB limits
  • you can send objects (not strings), eg. it uses AMF serialisation/deserialisation
  • it is more reliable, if the connection fails it will be restored etc.
TOPICS
Development

Views

303

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Nov 23, 2018 0
Enthusiast ,
Nov 23, 2018

Copy link to clipboard

Copied

maybe share some code?
how do you setup your sender and receiver?
are you listening for asyncError, securityError, etc.?

etc.

you mention "localhost" and "appname" but you should use a connection name starting with an underscore
see LocalConnection.send()

As discussed in the connect() entry, the current superdomain in added to connectionName by default. If you are implementing communication between different domains, you need to define connectionName in both the sending and receiving LocalConnection objects in such a way that the current superdomain is not added to connectionName. You can do this in one of the following two ways:

  • Use an underscore (_) at the beginning of connectionName in both the sending and receiving LocalConnection objects. In the file that contains the receiving object, use LocalConnection.allowDomain() to specify that connections from any domain will be accepted. This implementation lets you store your sending and receiving files in any domain.

  • Include the superdomain in connectionName in the sending LocalConnection object — for example, myDomain.com:myConnectionName. In the receiving object, use LocalConnection.allowDomain() to specify that connections from the specified superdomain will be accepted (in this case, myDomain.com) or that connections from any domain will be accepted.

in short,
receiver.connect( "_name" )

and
sender.send( "_name", "method", "arg1" )

now LocalConnection can be convenient but they use shared memory to communicate the messages (also why there is a limit of 40KB message) and so what you're experiencing could be another process accessing/modifying the same block of shared memory or whatnot, hard to say what it is without some debug, but the point here is that it uses shared memory and memory can be messed up with.

As an alternative (or backup) you could use NetConnection.connect()

with a connection string "rtmfp:" to create a serverless connection

Creates a two-way connection to an application on Flash Media Server or to Flash Remoting, or creates a two-way network endpoint for RTMFP peer-to-peer group communication. To report its status or an error condition, a call to NetConnection.connect() dispatches a netStatus event.

Call NetConnection.connect() to do the following:

  • Pass "null" to play video and mp3 files from a local file system or from a web server.
  • Pass an "http" URL to connect to an application server running Flash Remoting. Use the NetServices class to call functions on and return results from application servers over a NetConnection object. For more information, see the Flash Remoting documentation.
  • Pass an "rtmp/e/s" URL to connect to a Flash Media Server application.
  • Pass an "rtmfp" URL to create a two-way network endpoint for RTMFP client-server, peer-to-peer, and IP multicast communication.
  • Pass the string "rtmfp:" to create a serverless two-way network endpoint for RTMFP IP multicast communication.

see RTMFP FAQ
and Create a client-side serverless RTMFP connection


or see some library like

GitHub - palkan/as3_p2plocal: as3 lib for local p2p connections (serverless rtmfp)

so yeah it may seem a bit overkill but it is easy to setup and it has many advantages

  • no 40KB limits
  • you can send objects (not strings), eg. it uses AMF serialisation/deserialisation
  • it is more reliable, if the connection fails it will be restored etc.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 23, 2018 0
Explorer ,
Nov 24, 2018

Copy link to clipboard

Copied

Thanks! From what testers are telling me, the problem happens much more often when they have many applications open and the game is running slowly, so I guess other applications may indeed be changing the shared memory.

Either way, I've changed my code to check the connection every few seconds, remake the receiver if checks fail, and then re-send any data that failed to send while the connection was down. A bit clunky, but it works well enough, and hopefully the user won't notice. 

I'll look into NetConnection for any similar future projects, and see if it turns out to be more reliable.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Nov 24, 2018 0