PageRenderTime 20ms CodeModel.GetById 8ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 1ms

/flash-src/src/net/gimite/websocket/WebSocketMain.as

http://github.com/gimite/web-socket-js
ActionScript | 166 lines | 131 code | 23 blank | 12 comment | 12 complexity | 2e052987ea658e7005e2c089728e0906 MD5 | raw file
  1// Copyright: Hiroshi Ichikawa <http://gimite.net/en/>
  2// License: New BSD License
  3
  4package net.gimite.websocket {
  5
  6import flash.display.Sprite;
  7import flash.external.ExternalInterface;
  8import flash.system.Security;
  9import flash.utils.setTimeout;
 10
 11import mx.utils.URLUtil;
 12
 13/**
 14  * Provides JavaScript API of WebSocket.
 15  */
 16public class WebSocketMain extends Sprite implements IWebSocketLogger{
 17  
 18  private var callerUrl:String;
 19  private var debug:Boolean = false;
 20  private var manualPolicyFileLoaded:Boolean = false;
 21  private var webSockets:Array = [];
 22  private var eventQueue:Array = [];
 23  
 24  public function WebSocketMain() {
 25    ExternalInterface.addCallback("setCallerUrl", setCallerUrl);
 26    ExternalInterface.addCallback("setDebug", setDebug);
 27    ExternalInterface.addCallback("create", create);
 28    ExternalInterface.addCallback("send", send);
 29    ExternalInterface.addCallback("close", close);
 30    ExternalInterface.addCallback("loadManualPolicyFile", loadManualPolicyFile);
 31    ExternalInterface.addCallback("receiveEvents", receiveEvents);
 32    ExternalInterface.call("WebSocket.__onFlashInitialized");
 33  }
 34  
 35  public function setCallerUrl(url:String):void {
 36    callerUrl = url;
 37  }
 38  
 39  public function setDebug(val:Boolean):void {
 40    debug = val;
 41    if (val) {
 42      log("debug enabled");
 43    }
 44  }
 45  
 46  private function loadDefaultPolicyFile(wsUrl:String):void {
 47    var policyUrl:String = "xmlsocket://" + URLUtil.getServerName(wsUrl) + ":843";
 48    log("policy file: " + policyUrl);
 49    Security.loadPolicyFile(policyUrl);
 50  }
 51  
 52  public function loadManualPolicyFile(policyUrl:String):void {
 53    log("policy file: " + policyUrl);
 54    Security.loadPolicyFile(policyUrl);
 55    manualPolicyFileLoaded = true;
 56  }
 57  
 58  public function log(message:String):void {
 59    if (debug) {
 60      ExternalInterface.call("WebSocket.__log", encodeURIComponent("[WebSocket] " + message));
 61    }
 62  }
 63  
 64  public function error(message:String):void {
 65    ExternalInterface.call("WebSocket.__error", encodeURIComponent("[WebSocket] " + message));
 66  }
 67  
 68  private function parseEvent(event:WebSocketEvent):Object {
 69    var webSocket:WebSocket = event.target as WebSocket;
 70    var eventObj:Object = {};
 71    eventObj.type = event.type;
 72    eventObj.webSocketId = webSocket.getId();
 73    eventObj.readyState = webSocket.getReadyState();
 74    eventObj.protocol = webSocket.getAcceptedProtocol();
 75    if (event.message !== null) {
 76      eventObj.message = event.message;
 77    }
 78    if (event.wasClean) {
 79      eventObj.wasClean = event.wasClean;
 80    }
 81    if (event.code) {
 82      eventObj.code = event.code;
 83    }
 84    if (event.reason !== null) {
 85      eventObj.reason = event.reason;
 86    }
 87    return eventObj;
 88  }
 89  
 90  public function create(
 91      webSocketId:int,
 92      url:String, protocols:Array,
 93      proxyHost:String = null, proxyPort:int = 0,
 94      headers:String = null):void {
 95    if (!manualPolicyFileLoaded) {
 96      loadDefaultPolicyFile(url);
 97    }
 98    var newSocket:WebSocket = new WebSocket(
 99        webSocketId, url, protocols, getOrigin(), proxyHost, proxyPort,
100        getCookie(url), headers, this);
101    newSocket.addEventListener("open", onSocketEvent);
102    newSocket.addEventListener("close", onSocketEvent);
103    newSocket.addEventListener("error", onSocketEvent);
104    newSocket.addEventListener("message", onSocketEvent);
105    webSockets[webSocketId] = newSocket;
106  }
107  
108  public function send(webSocketId:int, encData:String):int {
109    var webSocket:WebSocket = webSockets[webSocketId];
110    return webSocket.send(encData);
111  }
112  
113  public function close(webSocketId:int):void {
114    var webSocket:WebSocket = webSockets[webSocketId];
115    webSocket.close();
116  }
117  
118  public function receiveEvents():Object {
119    var result:Object = eventQueue;
120    eventQueue = [];
121    return result;
122  }
123  
124  private function getOrigin():String {
125    return (URLUtil.getProtocol(this.callerUrl) + "://" +
126      URLUtil.getServerNameWithPort(this.callerUrl)).toLowerCase();
127  }
128  
129  private function getCookie(url:String):String {
130    if (URLUtil.getServerName(url).toLowerCase() ==
131        URLUtil.getServerName(this.callerUrl).toLowerCase()) {
132      return ExternalInterface.call("function(){return document.cookie}");
133    } else {
134      return "";
135    }
136  }
137  
138  /**
139   * Socket event handler.
140   */
141  public function onSocketEvent(event:WebSocketEvent):void {
142    var eventObj:Object = parseEvent(event);
143    eventQueue.push(eventObj);
144    processEvents();
145  }
146  
147  /**
148   * Process our event queue.  If javascript is unresponsive, set
149   * a timeout and try again.
150   */
151  public function processEvents():void {
152    if (eventQueue.length == 0) return;
153    try {
154      if (!ExternalInterface.call("WebSocket.__onFlashEvent")) {
155        setTimeout(processEvents, 500);
156      }
157    } catch(e:SecurityError){
158      trace(
159          "Caught SecurityError when trying to processEvents. " +
160          "This may happen when the window is going to be closed.");
161    }
162  }
163  
164}
165
166}