zoukankan      html  css  js  c++  java
  • 让ie6 7 8 9支持原生html5 websocket

     

    让ie6 7 8 9支持原生html5 websocket

     


      让ie6 7 8 9支持原生html5 websocket0

    让ie6 7 8 9支持原生html5 websocket1

      从github上的 web-socket-js (socket.io好像也是用这个做的他们的flash替代传输方式)改过来的。不过值得注意的是里面的flash websocket代理文件,文件实在是很大,有174k

    让ie6 7 8 9支持原生html5 websocket2

    很好奇,就反编译看下,

    让ie6 7 8 9支持原生html5 websocket3

    是flex做的,这点很不喜欢,因为我没有flex builder也不想因为去改代码重新装一个,然后mx包下面的是flex的组件,com包下是adobe封装的socket和两个加密包 .

    最下面那个包才是最主要的,代码不是很复杂,就是利用actionscript3的socket,与那边服务端socket握手,传递消息,不过区别是,在connect的时候要把header封装成websocket的样子

    让ie6 7 8 9支持原生html5 websocket4

    让ie6 7 8 9支持原生html5 websocket5

    这也是flash模拟websocket的原理。

    我花了点时间把源码里面和加密有关的代码都注释掉,加密的代码都是和wss(类似于https)有关的,用flash编译了一下,主要就是把mx包加到flash编译里面,flex是臃肿版的flash,结果大小只有20k!原来加密让文件大太多了!

    让ie6 7 8 9支持原生html5 websocket6

    websocket.js

      1 define("websocket", function() {
      2 (function() {
      3   if (window.WEB_SOCKET_FORCE_FLASH) {
      4     // Keeps going.
      5   } 
      6   else if (window.WebSocket) {
      7     return;
      8   } else if (window.MozWebSocket) {
      9     // Firefox.
     10     window.WebSocket = MozWebSocket;
     11     return;
     12   }
     13   var logger;
     14   if (window.WEB_SOCKET_LOGGER) {
     15     logger = WEB_SOCKET_LOGGER;
     16   } else if (window.console && window.console.log && window.console.error) {
     17     logger = window.console;
     18   } else {
     19     logger = {log: function(){ }, error: function(){ }};
     20   }
     21   window.WebSocket = function(url, protocols, proxyHost, proxyPort, headers) {
     22     var self = this;
     23     self.__id = WebSocket.__nextId++;
     24     WebSocket.__instances[self.__id] = self;
     25     self.readyState = WebSocket.CONNECTING;
     26     self.bufferedAmount = 0;
     27     self.__events = {};
     28     if (!protocols) {
     29       protocols = [];
     30     } else if (typeof protocols == "string") {
     31       protocols = [protocols];
     32     }
     33     self.__createTask = setTimeout(function() {
     34       WebSocket.__addTask(function() {
     35         self.__createTask = null;
     36         WebSocket.__flash.create(
     37             self.__id, url, protocols, proxyHost || null, proxyPort || 0, headers || null);
     38       });
     39     }, 0);
     40   };
     41   WebSocket.prototype.send = function(data) {
     42     if (this.readyState == WebSocket.CONNECTING) {
     43       throw "INVALID_STATE_ERR: Web Socket connection has not been established";
     44     }
     45     var result = WebSocket.__flash.send(this.__id, encodeURIComponent(data));
     46     if (result < 0) { // success
     47       return true;
     48     } else {
     49       this.bufferedAmount += result;
     50       return false;
     51     }
     52   };
     53   WebSocket.prototype.close = function() {
     54     if (this.__createTask) {
     55       clearTimeout(this.__createTask);
     56       this.__createTask = null;
     57       this.readyState = WebSocket.CLOSED;
     58       return;
     59     }
     60     if (this.readyState == WebSocket.CLOSED || this.readyState == WebSocket.CLOSING) {
     61       return;
     62     }
     63     this.readyState = WebSocket.CLOSING;
     64     WebSocket.__flash.close(this.__id);
     65   };
     66   WebSocket.prototype.dispatchEvent = function(event) {
     67     var events = this.__events[event.type] || [];
     68     for (var i = 0; i < events.length; ++i) {
     69       events[i](event);
     70     }
     71     var handler = this["on" + event.type];
     72     if (handler) handler.apply(this, [event]);
     73   };
     74   WebSocket.prototype.__handleEvent = function(flashEvent) {
     75     if ("readyState" in flashEvent) {
     76       this.readyState = flashEvent.readyState;
     77     }
     78     if ("protocol" in flashEvent) {
     79       this.protocol = flashEvent.protocol;
     80     }
     81     var jsEvent;
     82     if (flashEvent.type == "open" || flashEvent.type == "error") {
     83       jsEvent = this.__createSimpleEvent(flashEvent.type);
     84     } else if (flashEvent.type == "close") {
     85       jsEvent = this.__createSimpleEvent("close");
     86       jsEvent.wasClean = flashEvent.wasClean ? true : false;
     87       jsEvent.code = flashEvent.code;
     88       jsEvent.reason = flashEvent.reason;
     89     } else if (flashEvent.type == "message") {
     90       var data = decodeURIComponent(flashEvent.message);
     91       jsEvent = this.__createMessageEvent("message", data);
     92     } else {
     93       throw "unknown event type: " + flashEvent.type;
     94     }
     95     this.dispatchEvent(jsEvent);
     96   };
     97   WebSocket.prototype.__createSimpleEvent = function(type) {
     98     if (document.createEvent && window.Event) {
     99       var event = document.createEvent("Event");
    100       event.initEvent(type, false, false);
    101       return event;
    102     } else {
    103       return {type: type, bubbles: false, cancelable: false};
    104     }
    105   };
    106   WebSocket.prototype.__createMessageEvent = function(type, data) {
    107     if (window.MessageEvent && typeof(MessageEvent) == "function" && !window.opera) {
    108       return new MessageEvent("message", {
    109         "view": window,
    110         "bubbles": false,
    111         "cancelable": false,
    112         "data": data
    113       });
    114     } else if (document.createEvent && window.MessageEvent && !window.opera) {
    115       var event = document.createEvent("MessageEvent");
    116         event.initMessageEvent("message", false, false, data, null, null, window, null);
    117       return event;
    118     } else {
    119       return {type: type, data: data, bubbles: false, cancelable: false};
    120     }
    121   };
    122   WebSocket.CONNECTING = 0;
    123   WebSocket.OPEN = 1;
    124   WebSocket.CLOSING = 2;
    125   WebSocket.CLOSED = 3;
    126   WebSocket.__isFlashImplementation = true;
    127   WebSocket.__initialized = false;
    128   WebSocket.__flash = null;
    129   WebSocket.__instances = {};
    130   WebSocket.__tasks = [];
    131   WebSocket.__nextId = 0;
    132   WebSocket.loadFlashPolicyFile = function(url){
    133     WebSocket.__addTask(function() {
    134       WebSocket.__flash.loadManualPolicyFile(url);
    135     });
    136   };
    137   WebSocket.__initialize = function() {
    138     if (WebSocket.__initialized) return;
    139     WebSocket.__initialized = true;
    140     if (WebSocket.__swfLocation) {
    141       window.WEB_SOCKET_SWF_LOCATION = WebSocket.__swfLocation;
    142     }
    143   };
    144   WebSocket.__onFlashInitialized = function() {
    145     setTimeout(function() {
    146       WebSocket.__flash =main.get_flash_obj("webSocketFlash");
    147       WebSocket.__flash.setCallerUrl(location.href);
    148       WebSocket.__flash.setDebug(!!window.WEB_SOCKET_DEBUG);
    149       for (var i = 0; i < WebSocket.__tasks.length; ++i) {
    150         WebSocket.__tasks[i]();
    151       }
    152       WebSocket.__tasks = [];
    153     }, 0);
    154   };
    155   WebSocket.__onFlashEvent = function() {
    156     setTimeout(function() {
    157       try {
    158         var events = WebSocket.__flash.receiveEvents();
    159         for (var i = 0; i < events.length; ++i) {
    160           WebSocket.__instances[events[i].webSocketId].__handleEvent(events[i]);
    161         }
    162       } catch (e) {
    163         logger.error(e);
    164       }
    165     }, 0);
    166     return true;
    167   };
    168   WebSocket.__log = function(message) {
    169     logger.log(decodeURIComponent(message));
    170   };
    171   WebSocket.__error = function(message) {
    172     logger.error(decodeURIComponent(message));
    173   };
    174   WebSocket.__addTask = function(task) {
    175     if (WebSocket.__flash) {
    176       task();
    177     } else {
    178       WebSocket.__tasks.push(task);
    179     }
    180   };
    181 })();
    182 return WebSocket;
    183 });

    websocket_main.js

     1 require(['html5/websocket','avalon-min'],function(WebSocket,avalon){
     2     var $=function(id){
     3         return document.getElementById(id);
     4     };
     5     WEB_SOCKET_DEBUG = true;
     6     var ws;
     7         ws = new WebSocket("ws://localhost:8888/new-msg/socket");
     8         ws.onopen = function() {
     9             output("onopen");
    10         };
    11         ws.onmessage = function(e) {
    12             output("onmessage: " + e.data);
    13         };
    14         ws.onclose = function() {
    15             output("onclose");
    16         };
    17         ws.onerror = function() {
    18             output("onerror");
    19         };
    20     avalon.bind($('send'),'click',function(){
    21             var input = $("input1");
    22             ws.send(input.value);
    23             output("send: " + input.value);
    24             input.value = "";
    25             input.focus();
    26     });
    27     avalon.bind($('close'),'click',function(){
    28             ws.close();
    29     });
    30     function output(str) {
    31         var log = document.getElementById("log");
    32         var escaped = str.replace(/&/, "&amp;").replace(/</, "&lt;")
    33                 .replace(/>/, "&gt;").replace(/"/, "&quot;"); // "
    34         log.innerHTML = escaped + "<br>" + log.innerHTML;
    35     }
    36 });
     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     5 <title>Insert title here</title>
     6 <script src="http://localhost/twitter/js/libs/seed-min.js"></script>
     7 <script type="text/javascript"
     8     src="http://localhost/twitter/js/libs/flash_embed.js"></script>
     9 <script src="http://localhost/twitter/js/main.js" type="text/javascript"></script>
    10 </head>
    11 <body>
    12     <input type="text" id="input1">
    13     <input type="submit" value="Send" id='send'>
    14     <button id='close'>close</button>
    15     <div id="log"></div>
    16     <div id='a' style=' 1px; height: 1px;'></div>
    17     <script type="text/javascript">
    18         flash_object.embedSWF('http://localhost:8888/swf/WebSocketMain.swf',
    19                 'a', 'webSocketFlash', '100%', '100%');
    20     </script>
    21     <script type="text/javascript"
    22         src='http://localhost/twitter/js/libs/html5/websocket_main.js'></script>
    23 </body>
    24 </html>

    下面很重要,在运行前一定要开启服务端(python)的socket

     1 import socket
     2 import time
     3 from threading import Thread
     4 
     5 class returnCrossDomain(Thread):
     6     def __init__(self,connection):
     7         Thread.__init__(self)
     8         self.con = connection
     9     def run(self):
    10         clientData  = self.con.recv(1024)
    11         xmlData  = '''<?xml version="1.0" encoding="utf-8"?>'''
    12         xmlData += '''<cross-domain-policy><policy-file-request/>'''
    13         xmlData += '''<allow-access-from domain="*" to-ports="*" />'''
    14     xmlData += '''</cross-domain-policy>'''
    15         try:
    16             self.con.send(xmlData)
    17         except Excepiton,e:
    18             pass
    19         self.con.close()
    20 def main():
    21     sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    22     sock.bind(('localhost',843))
    23     sock.listen(10000000)
    24     print 'socket'
    25     while True:
    26         try:
    27             connection,address = sock.accept()
    28             returnCrossDomain(connection).start()
    29         except:
    30             time.sleep(1)
    31 
    32 if __name__=="__main__":
    33     main()

    服务端用python的tornado写的,也一样在运行前开启tornado

     1 # -*- coding: utf-8 -*-
     2 import base
     3 import tornado.websocket
     4 
     5 def send_message(message):
     6     for handler in ChatSocketHandler.socket_handlers:
     7         handler.write_message(message)
     8 
     9 class ChatSocketHandler(tornado.websocket.WebSocketHandler):
    10     socket_handlers = set()
    11 
    12     def open(self):
    13         ChatSocketHandler.socket_handlers.add(self)
    14         print 'websocket'
    15         send_message('A new user has entered the chat room.')
    16 
    17     def on_close(self):
    18         ChatSocketHandler.socket_handlers.remove(self)
    19         print 'websocket close'
    20         send_message('A user has left the chat room.')
    21 
    22     def on_message(self, message):
    23         print 'message:'+message
    24         send_message(message)

    tornado很好的封装了websocket,用起来很简单,加上flash模拟websocket兼容不支持websocket的浏览器,这样可以完美的利用高效的websocket.

    如果嫌弃flash的话,还是用ajax长连接,tornado很好的支持ajax长连接,性能很好

     WebSocketMain.swf文件及源码:http://files.cnblogs.com/TheViper/flash_websocket.zip

  • 相关阅读:
    java 面试每日一题2
    java 面试每日一题
    java GUI画满天星
    java JPEGImageEncoder;图像处理
    spring mvc+myBatis配置详解
    myeclipse 常用快捷键总结
    Java 如何快速序列化
    java UUID
    vue +echarts树状图
    在线预览(pptx、ppt、pps、docx、doc、xlsx、xls)
  • 原文地址:https://www.cnblogs.com/lidabo/p/6374979.html
Copyright © 2011-2022 走看看