AS lib classes for running multiple concurent socket conections

I got the idea for this when I needed to connect to a C/C++ back-end server. The server(s) could process incoming requests on several ports: 80, 81, 8082, etc… Initially I thought to just pick-up a random port from the list and try to connect to that. It worked just fine but I felt like something was missing… Then I thought that I could try to connect on the first port and if the connection fails move to the next one and so on…, somehow better (or not!), since the ports on the end of the list would rarely get a fair to be used… Finally I came across Fernando Flores’ Function library which is pretty much dealing with issue of connecting to multiple hosts/ports using NetConnections. He’s idea is to run concurrent net connections on all server/ports, the first successful connection is kept while the rest are discarded. This way you will always be using the fastest connection. My code pretty much applies the same idea to socket connections.

There are 5 classes in the .zip file. EnhancedSocket (as it’s name states) enhances the functionality flash.net.Socket, by adding a timeout. The socket class has a timeout public property, since FP10. However, even if set to a custom value, it doesn’t seem to affect the default behavior, which is to dispatch a SecurityErrorEvent if it fails to connect in 21 seconds. EnhancedSocket dispatches a timeout Event (in the current implementation this is the o TimerEvent.TIMER) if the socket fails to connect within the specified timeout range (default is 6 seconds unless set otherwise).

SocketChannel is a configuration helper class used to feed input parameters into the enhanced socket: host, port, timeout (if set this overwrites the default timeout value in the enhanced socket), the maximum number of timeouts retries and the maximum number of failure retries.

SocketService class is doing all the logic. Creates socket connections based on the already declared channels and handles them accordingly. It uses the ServiceEvent custom class to communicate with it’s client/broker… The class also exposes a public send() method which takes a ByteArray as input parameter, useful for sending bytes to the server.

TestSocketsService (listed below) is a small sample of how you can make use of the whole mechanism.

package
{
	import flash.display.Sprite;
	import ro.apartment223.net.SocketService;
	import ro.apartment223.net.ServiceEvent;
	import ro.apartment223.net.SocketChannel;
	
	public class TestSocketsService extends Sprite
	{
		private var _service:SocketService;
		
		public function TestSocketsService()
		{
			var channelSet:Vector.<SocketChannel> = Vector.<SocketChannel>([new SocketChannel("127.0.0.1", 8082), new SocketChannel("127.0.0.1", 80), new SocketChannel("127.0.0.1", 81), new SocketChannel("127.0.0.1", 1300)]);			
			_service = new SocketService(channelSet);
			_service.addEventListener(ServiceEvent.SERVICE_CONNECTED, onServiceConnected);
			_service.addEventListener(ServiceEvent.SERVICE_DATA, onServiceData);
			_service.addEventListener(ServiceEvent.SERVICE_ERROR, onServiceError);
			_service.addEventListener(ServiceEvent.SERVICE_SECURITY_ERROR, onServiceSecurityError);
			_service.addEventListener(ServiceEvent.SERVICE_CLOSED, onServiceClosed);
			
			_service.connect();
		}
		
		private function onServiceConnected(event:ServiceEvent):void
		{
			trace("service connected");
		}

		private function onServiceData(event:ServiceEvent):void
		{
			trace("service data = ", event.data);
		}

		private function onServiceError(event:ServiceEvent):void
		{
			/**implement retry policy **/
			trace("service error = ", event.data);
		}
		
		private function onServiceSecurityError(event:ServiceEvent):void
		{
			trace("service security error");
		}
		
		private function onServiceClosed(event:ServiceEvent):void
		{
			trace("service closed");
			/**implement retry policy **/
			/** _service.connect(); **/
		}		
	}
}

Feel free to DOWNLOAD the code, play with it, improve it (give me a shout if you do so), it is free of any charge.

Leave a Reply

Your email address will not be published. Required fields are marked *

*