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