aboutsummaryrefslogtreecommitdiffstats
path: root/signaling-server/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/WebSocketMain.as
blob: 1bf3d7ecbfe85df0d3c8eaed71abf14f936f8286 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright: Hiroshi Ichikawa <http://gimite.net/en/>
// License: New BSD License
// Reference: http://dev.w3.org/html5/websockets/
// Reference: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76

package {

import flash.display.Sprite;
import flash.external.ExternalInterface;
import flash.system.Security;
import flash.utils.setTimeout;

import mx.utils.URLUtil;

/**
  * Provides JavaScript API of WebSocket.
  */
public class WebSocketMain extends Sprite implements IWebSocketLogger{
  
  private var callerUrl:String;
  private var debug:Boolean = false;
  private var manualPolicyFileLoaded:Boolean = false;
  private var webSockets:Array = [];
  private var eventQueue:Array = [];
  
  public function WebSocketMain() {
    ExternalInterface.addCallback("setCallerUrl", setCallerUrl);
    ExternalInterface.addCallback("setDebug", setDebug);
    ExternalInterface.addCallback("create", create);
    ExternalInterface.addCallback("send", send);
    ExternalInterface.addCallback("close", close);
    ExternalInterface.addCallback("loadManualPolicyFile", loadManualPolicyFile);
    ExternalInterface.addCallback("receiveEvents", receiveEvents);
    ExternalInterface.call("WebSocket.__onFlashInitialized");
  }
  
  public function setCallerUrl(url:String):void {
    callerUrl = url;
  }
  
  public function setDebug(val:Boolean):void {
    debug = val;
  }
  
  private function loadDefaultPolicyFile(wsUrl:String):void {
    var policyUrl:String = "xmlsocket://" + URLUtil.getServerName(wsUrl) + ":843";
    log("policy file: " + policyUrl);
    Security.loadPolicyFile(policyUrl);
  }
  
  public function loadManualPolicyFile(policyUrl:String):void {
    log("policy file: " + policyUrl);
    Security.loadPolicyFile(policyUrl);
    manualPolicyFileLoaded = true;
  }
  
  public function log(message:String):void {
    if (debug) {
      ExternalInterface.call("WebSocket.__log", encodeURIComponent("[WebSocket] " + message));
    }
  }
  
  public function error(message:String):void {
    ExternalInterface.call("WebSocket.__error", encodeURIComponent("[WebSocket] " + message));
  }
  
  private function parseEvent(event:WebSocketEvent):Object {
    var webSocket:WebSocket = event.target as WebSocket;
    var eventObj:Object = {};
    eventObj.type = event.type;
    eventObj.webSocketId = webSocket.getId();
    eventObj.readyState = webSocket.getReadyState();
    eventObj.protocol = webSocket.getAcceptedProtocol();
    if (event.message !== null) {
      eventObj.message = event.message;
    }
    return eventObj;
  }
  
  public function create(
      webSocketId:int,
      url:String, protocols:Array,
      proxyHost:String = null, proxyPort:int = 0,
      headers:String = null):void {
    if (!manualPolicyFileLoaded) {
      loadDefaultPolicyFile(url);
    }
    var newSocket:WebSocket = new WebSocket(
        webSocketId, url, protocols, getOrigin(), proxyHost, proxyPort,
        getCookie(url), headers, this);
    newSocket.addEventListener("open", onSocketEvent);
    newSocket.addEventListener("close", onSocketEvent);
    newSocket.addEventListener("error", onSocketEvent);
    newSocket.addEventListener("message", onSocketEvent);
    webSockets[webSocketId] = newSocket;
  }
  
  public function send(webSocketId:int, encData:String):int {
    var webSocket:WebSocket = webSockets[webSocketId];
    return webSocket.send(encData);
  }
  
  public function close(webSocketId:int):void {
    var webSocket:WebSocket = webSockets[webSocketId];
    webSocket.close();
  }
  
  public function receiveEvents():Object {
    var result:Object = eventQueue;
    eventQueue = [];
    return result;
  }
  
  private function getOrigin():String {
    return (URLUtil.getProtocol(this.callerUrl) + "://" +
      URLUtil.getServerNameWithPort(this.callerUrl)).toLowerCase();
  }
  
  private function getCookie(url:String):String {
    if (URLUtil.getServerName(url).toLowerCase() ==
        URLUtil.getServerName(this.callerUrl).toLowerCase()) {
      return ExternalInterface.call("function(){return document.cookie}");
    } else {
      return "";
    }
  }
  
  /**
   * Socket event handler.
   */
  public function onSocketEvent(event:WebSocketEvent):void {
    var eventObj:Object = parseEvent(event);
    eventQueue.push(eventObj);
    processEvents();
  }
  
  /**
   * Process our event queue.  If javascript is unresponsive, set
   * a timeout and try again.
   */
  public function processEvents():void {
    if (eventQueue.length == 0) return;
    if (!ExternalInterface.call("WebSocket.__onFlashEvent")) {
      setTimeout(processEvents, 500);
    }
  }
  
}

}