Handling websocket connections with Adobe AIR ServerSocket

Handling websocket connections with Adobe AIR ServerSocket

Since Adobe AIR 2.0, you can create your own socket-servers, using the flash.net.ServerSocket class. This makes it easy to hook external applications to your AIR applications, for example to create a game (server) with multiple devices as game controllers (socket clients).

With an adobe air serversocket, most of the time, the clients will be other flash-based applications (swfs or native apps built with Adobe AIR). HTML5 introduced the concept of websockets: a way to create your own socket connections from an html page (using javascript) to a server. You’ll need to implement the right protocol to handle these connections, but with some work, you’re able to create an html/js mobile controller for an Adobe AIR application. Big advantage here is you don’t need to install a native application, you can just surf to a url, and start sending data between your client and your server.

Server side

First of all, I’ll go through the code on the server. I assume you’ve created an Adobe AIR 2.0 (or higher) project in your AS editor of choice. First of all, you’ll need to create an instance of the ServerSocket class and hook up some event listeners:

serverSocket = new ServerSocket();
serverSocket.addEventListener(ServerSocketConnectEvent.CONNECT, clientConnectHandler, false, 0, true);
serverSocket.bind(1235);
serverSocket.listen();

Whenever a client connects, I create an instance of an own-written client handler class, which will manage the connected client. I manage all clienthandlers in a global clientHandlers array.

private function clientConnectHandler(event:ServerSocketConnectEvent):void
{
   var clientHandler:ClientHandler = new ClientHandler(event.socket);
   clientHandler.addEventListener(Event.CLOSE, clientHandlerCloseHandler, false, 0, true);
   clientHandlers.push(clientHandler);
}

The clienthandler instances, manage all communication between the server and the client. This is where some of the websocket-specific stuff comes in: the first message the server receives, is a handshake. We’ll need to send back a specific message to the client, otherwise the client will drop the connection with the server. Read more about websockets and this handshake mechanism on wikipedia.

We listen for data in this clientHandler class:

public function ClientHandler(socket:Socket)
{
   this.socket = socket;
   socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler, false, 0, true);
}

And inside this socketDataHandler, we’ll find the handshake logic:

private function socketDataHandler(event:ProgressEvent):void
{
   if(socket.bytesAvailable > 0)
   {
      if(!firstRequestProcessed)
      {
         firstRequestProcessed = true;
         var message:String = socketBytes.readUTFBytes(socketBytes.bytesAvailable);
         if(message.indexOf("GET ") == 0)
         {
            var messageLines:Array = message.split("\n");
            var fields:Object = {};
            var requestedURL:String = "";
            for(var i:uint = 0; i < messageLines.length; i++)
            {
               var line:String = messageLines[i];
               if(i == 0)
               {
                  var getSplit:Array = line.split(" ");
                  if(getSplit.length > 1)
                  {
                     requestedURL = getSplit[1];
                  }
               }
               else
               {
                  var index:int = line.indexOf(":");
                  if(index > -1)
                  {
                     var key:String = line.substr(0, index);
                     fields[key] = line.substr(index + 1).replace( /^([\s|\t|\n]+)?(.*)([\s|\t|\n]+)?$/gm, "$2" );
                  }
               }
            }
            //check the websocket version
            if(fields["Sec-WebSocket-Version"] != null)
            {
               //NOT SUPPORTED YET
            }
            else
            {
               if(fields["Sec-WebSocket-Key1"] != null && fields["Sec-WebSocket-Key2"] != null)
               {
                  //draft-ietf-hybi-thewebsocketprotocol-00
                  //send a response
                  var result:* = fields["Sec-WebSocket-Key1"].match(/[0-9]/gi);
                  var key1Nr:uint = (result is Array) ? uint(result.join("")) : 1;
                  result = fields["Sec-WebSocket-Key1"].match(/ /gi);
                  var key1SpaceCount:uint = (result is Array) ? result.length : 1;
                  var key1Part:Number = key1Nr / key1SpaceCount;
 
                  result = fields["Sec-WebSocket-Key2"].match(/[0-9]/gi);
                  var key2Nr:uint = (result is Array) ? uint(result.join("")) : 1;
                  result = fields["Sec-WebSocket-Key2"].match(/ /gi);
                  var key2SpaceCount:uint = (result is Array) ? result.length : 1;
                  var key2Part:Number = key2Nr / key2SpaceCount;
 
                  //calculate binary md5 hash
                  var bytesToHash:ByteArray = new ByteArray();
                  bytesToHash.writeUnsignedInt(key1Part);
                  bytesToHash.writeUnsignedInt(key2Part);
                  bytesToHash.writeBytes(socketBytes, socketBytes.length - 8);
 
                  //hash it
                  var hash:String = MD5.hashBytes(bytesToHash);
 
                  var response:String = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" +
                     "Upgrade: WebSocket\r\n" +
                     "Connection: Upgrade\r\n" +
                     "Sec-WebSocket-Origin: " + fields["Origin"] + "\r\n" +
                     "Sec-WebSocket-Location: ws://" + fields["Host"] + requestedURL + "\r\n" +
                     "\r\n";
                  var responseBytes:ByteArray = new ByteArray();
                  responseBytes.writeUTFBytes(response);
 
                  for(i = 0; i < hash.length; i += 2)
                  {
                     responseBytes.writeByte(parseInt(hash.substr(i, 2), 16));
                  }
 
                  responseBytes.writeByte(0);
                  responseBytes.position = 0;
                  socket.writeBytes(responseBytes);
                  socket.flush();
                  //stop right here
                  socketBytes.clear();
                  return;
               }
            }
         }
      }
      else
      {
         //do something else with the data
      }
   }
}

This will accept a websocket connection and send back the correct handshake. So, how do you connect from html / javascript to this AIR server?

HTML5 Websocket client

You’ll connect to the AIR server using javascript. This is pretty straightforward: you create a WebSocket object, link the correct event handlers and connect to the air server on the correct port:

function init()
{
   try
   {
      socket = new WebSocket("ws://localhost:1235");
      socket.onopen = socketOpenHandler;
      socket.onmessage = socketMessageHandler;
      socket.onclose = socketCloseHandler;
   }
   catch(exception)
   {
      alert("Error: " + exception);
   }
}
 
function socketOpenHandler()
{
   //connected to the server
}
 
function socketMessageHandler(message)
{
   //message received: message.data
}
 
function socketCloseHandler()
{
   //connection closed
}

That’s it. Fire up your Adobe AIR server, and you should be able to connect to the Adobe AIR application from javascript!

I’ll post some examples & a utility library in a follow-up post, so stay tuned :-)

Update: Check http://blog.aboutme.be/2011/11/24/airserver-support-for-websocket-version-8/ for a library and demos.

1 Response to “Handling websocket connections with Adobe AIR ServerSocket”
  • Hello,

    I am working on this myselfs, but i am unable to get it working.
    My client instantly disconnects(Client notified socket has closed close )

    If you could contact me at my email adress i would be realy pleased.
    I’m trying to write an article about this, but i’m really unable to get the connection setup ;(

    Thx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
之间有什么不同?可以回忆一下socket并学习一下websocket吗? 回答: ServersocketWebsocket是两种不同的通信协议。Serversocket是Java中用于实现服务器端的Socket编程的类,它用于监听指定端口并接受客户端的连接请求。通过Serversocket,服务器可以创建一个Socket对象与客户端进行通信。\[2\]而Websocket是一种在Web浏览器和服务器之间进行全双工通信的协议。它允许服务器主动向客户端推送数据,而不需要客户端发送请求。Websocket使用HTTP协议进行握手,然后在建立连接后,通过长连接实现实时通信。Websocket通常用于实时聊天、实时数据更新等场景。 关于Socket的回忆,Socket是一种在应用层和下面所有层之间的通信接口,它可以帮助我们以相对简单的方式进行网络通信。Socket可以用于实现客户端和服务器之间的通信,通过Socket可以建立连接、发送和接收数据。在Socket编程中,服务器端需要创建一个ServerSocket对象来监听指定端口并接受客户端的连接请求,而客户端则需要创建一个Socket对象来连接服务器。通过Socket对象的输入流和输出流,可以进行数据的读写操作。\[3\] 总结起来,Serversocket是用于实现服务器端的Socket编程的类,而Websocket是一种在Web浏览器和服务器之间进行全双工通信的协议。Socket编程是一种通用的网络编程方式,可以用于实现各种类型的网络通信。 #### 引用[.reference_title] - *1* [Socket,ServerSocketWebSocket](https://blog.csdn.net/u013123635/article/details/78773363)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [socket通信的简单实现(serversocket),以及对websocket的一些认识](https://blog.csdn.net/qq_37585801/article/details/88748217)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值