`

让ie6 7 8 9支持html5 websocket

 
阅读更多

结果:



 


 

 

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

很好奇,就反编译看下,

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

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

 

这也是flash模拟websocket的原理。事实上,直接用flash的socket就可以完成与服务端的双向信息传递,不过缺点是需要在服务端的socket代码写很多其他的代码,比如多线程,信息解析等,直接用websocket就不用写那些多余的代码了。

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

 

websocket.js

 

define("websocket", function() {
(function() {
  if (window.WEB_SOCKET_FORCE_FLASH) {
    // Keeps going.
  } 
  else if (window.WebSocket) {
    return;
  } else if (window.MozWebSocket) {
    // Firefox.
    window.WebSocket = MozWebSocket;
    return;
  }
  var logger;
  if (window.WEB_SOCKET_LOGGER) {
    logger = WEB_SOCKET_LOGGER;
  } else if (window.console && window.console.log && window.console.error) {
    logger = window.console;
  } else {
    logger = {log: function(){ }, error: function(){ }};
  }
  window.WebSocket = function(url, protocols, proxyHost, proxyPort, headers) {
    var self = this;
    self.__id = WebSocket.__nextId++;
    WebSocket.__instances[self.__id] = self;
    self.readyState = WebSocket.CONNECTING;
    self.bufferedAmount = 0;
    self.__events = {};
    if (!protocols) {
      protocols = [];
    } else if (typeof protocols == "string") {
      protocols = [protocols];
    }
    self.__createTask = setTimeout(function() {
      WebSocket.__addTask(function() {
        self.__createTask = null;
        WebSocket.__flash.create(
            self.__id, url, protocols, proxyHost || null, proxyPort || 0, headers || null);
      });
    }, 0);
  };
  WebSocket.prototype.send = function(data) {
    if (this.readyState == WebSocket.CONNECTING) {
      throw "INVALID_STATE_ERR: Web Socket connection has not been established";
    }
    var result = WebSocket.__flash.send(this.__id, encodeURIComponent(data));
    if (result < 0) { // success
      return true;
    } else {
      this.bufferedAmount += result;
      return false;
    }
  };
  WebSocket.prototype.close = function() {
    if (this.__createTask) {
      clearTimeout(this.__createTask);
      this.__createTask = null;
      this.readyState = WebSocket.CLOSED;
      return;
    }
    if (this.readyState == WebSocket.CLOSED || this.readyState == WebSocket.CLOSING) {
      return;
    }
    this.readyState = WebSocket.CLOSING;
    WebSocket.__flash.close(this.__id);
  };
  WebSocket.prototype.dispatchEvent = function(event) {
    var events = this.__events[event.type] || [];
    for (var i = 0; i < events.length; ++i) {
      events[i](event);
    }
    var handler = this["on" + event.type];
    if (handler) handler.apply(this, [event]);
  };
  WebSocket.prototype.__handleEvent = function(flashEvent) {
    if ("readyState" in flashEvent) {
      this.readyState = flashEvent.readyState;
    }
    if ("protocol" in flashEvent) {
      this.protocol = flashEvent.protocol;
    }
    var jsEvent;
    if (flashEvent.type == "open" || flashEvent.type == "error") {
      jsEvent = this.__createSimpleEvent(flashEvent.type);
    } else if (flashEvent.type == "close") {
      jsEvent = this.__createSimpleEvent("close");
      jsEvent.wasClean = flashEvent.wasClean ? true : false;
      jsEvent.code = flashEvent.code;
      jsEvent.reason = flashEvent.reason;
    } else if (flashEvent.type == "message") {
      var data = decodeURIComponent(flashEvent.message);
      jsEvent = this.__createMessageEvent("message", data);
    } else {
      throw "unknown event type: " + flashEvent.type;
    }
    this.dispatchEvent(jsEvent);
  };
  WebSocket.prototype.__createSimpleEvent = function(type) {
    if (document.createEvent && window.Event) {
      var event = document.createEvent("Event");
      event.initEvent(type, false, false);
      return event;
    } else {
      return {type: type, bubbles: false, cancelable: false};
    }
  };
  WebSocket.prototype.__createMessageEvent = function(type, data) {
    if (window.MessageEvent && typeof(MessageEvent) == "function" && !window.opera) {
      return new MessageEvent("message", {
        "view": window,
        "bubbles": false,
        "cancelable": false,
        "data": data
      });
    } else if (document.createEvent && window.MessageEvent && !window.opera) {
      var event = document.createEvent("MessageEvent");
        event.initMessageEvent("message", false, false, data, null, null, window, null);
      return event;
    } else {
      return {type: type, data: data, bubbles: false, cancelable: false};
    }
  };
  WebSocket.CONNECTING = 0;
  WebSocket.OPEN = 1;
  WebSocket.CLOSING = 2;
  WebSocket.CLOSED = 3;
  WebSocket.__isFlashImplementation = true;
  WebSocket.__initialized = false;
  WebSocket.__flash = null;
  WebSocket.__instances = {};
  WebSocket.__tasks = [];
  WebSocket.__nextId = 0;
  WebSocket.loadFlashPolicyFile = function(url){
    WebSocket.__addTask(function() {
      WebSocket.__flash.loadManualPolicyFile(url);
    });
  };
  WebSocket.__initialize = function() {
    if (WebSocket.__initialized) return;
    WebSocket.__initialized = true;
    if (WebSocket.__swfLocation) {
      window.WEB_SOCKET_SWF_LOCATION = WebSocket.__swfLocation;
    }
  };
  WebSocket.__onFlashInitialized = function() {
    setTimeout(function() {
      WebSocket.__flash =main.get_flash_obj("webSocketFlash");
      WebSocket.__flash.setCallerUrl(location.href);
      WebSocket.__flash.setDebug(!!window.WEB_SOCKET_DEBUG);
      for (var i = 0; i < WebSocket.__tasks.length; ++i) {
        WebSocket.__tasks[i]();
      }
      WebSocket.__tasks = [];
    }, 0);
  };
  WebSocket.__onFlashEvent = function() {
    setTimeout(function() {
      try {
        var events = WebSocket.__flash.receiveEvents();
        for (var i = 0; i < events.length; ++i) {
          WebSocket.__instances[events[i].webSocketId].__handleEvent(events[i]);
        }
      } catch (e) {
        logger.error(e);
      }
    }, 0);
    return true;
  };
  WebSocket.__log = function(message) {
    logger.log(decodeURIComponent(message));
  };
  WebSocket.__error = function(message) {
    logger.error(decodeURIComponent(message));
  };
  WebSocket.__addTask = function(task) {
    if (WebSocket.__flash) {
      task();
    } else {
      WebSocket.__tasks.push(task);
    }
  };
})();
return WebSocket;
});
 

websocket_main.js

 

require(['html5/websocket','avalon-min'],function(WebSocket,avalon){
    var $=function(id){
        return document.getElementById(id);
    };
    WEB_SOCKET_DEBUG = true;
    var ws;
        ws = new WebSocket("ws://localhost:8888/new-msg/socket");
        ws.onopen = function() {
            output("onopen");
        };
        ws.onmessage = function(e) {
            output("onmessage: " + e.data);
        };
        ws.onclose = function() {
            output("onclose");
        };
        ws.onerror = function() {
            output("onerror");
        };
    avalon.bind($('send'),'click',function(){
            var input = $("input1");
            ws.send(input.value);
            output("send: " + input.value);
            input.value = "";
            input.focus();
    });
    avalon.bind($('close'),'click',function(){
            ws.close();
    });
    function output(str) {
        var log = document.getElementById("log");
        var escaped = str.replace(/&/, "&amp;").replace(/</, "&lt;")
                .replace(/>/, "&gt;").replace(/"/, "&quot;"); // "
        log.innerHTML = escaped + "<br>" + log.innerHTML;
    }
});
 HTML:

 

 

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script src="http://localhost/twitter/js/libs/seed-min.js"></script>
<script type="text/javascript" src="http://localhost/twitter/js/libs/flash_embed.js"></script>
<script src="http://localhost/twitter/js/main.js" type="text/javascript"></script>
</head>
<body>
    <input type="text" id="input1">
    <input type="submit" value="Send" id='send'>
    <button id='close'>close</button>
    <div id="log"></div>
    <div id='a' style='width: 1px; height: 1px;'></div>
    <script type="text/javascript">
        flash_object.embedSWF('http://localhost:8888/swf/WebSocketMain.swf', 'a', 'webSocketFlash', '100%', '100%');
    </script>
    <script type="text/javascript" src='http://localhost/twitter/js/libs/html5/websocket_main.js'></script>
</body>
</html>
 

 

 

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

 

import socket
import time
from threading import Thread

class returnCrossDomain(Thread):
    def __init__(self,connection):
        Thread.__init__(self)
        self.con = connection
    def run(self):
        clientData  = self.con.recv(1024)
        xmlData  = '''<?xml version="1.0" encoding="utf-8"?>'''
        xmlData += '''<cross-domain-policy><policy-file-request/>'''
        xmlData += '''<allow-access-from domain="*" to-ports="*" />'''
    xmlData += '''</cross-domain-policy>\0'''
        try:
            self.con.send(xmlData)
        except Excepiton,e:
            pass
        self.con.close()
def main():
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    sock.bind(('localhost',843))
    sock.listen(10000000)
    print 'socket'
    while True:
        try:
            connection,address = sock.accept()
            returnCrossDomain(connection).start()
        except:
            time.sleep(1)

if __name__=="__main__":
    main()
 

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

# -*- coding: utf-8 -*-
import base
import tornado.websocket

def send_message(message):
    for handler in ChatSocketHandler.socket_handlers:
        handler.write_message(message)

class ChatSocketHandler(tornado.websocket.WebSocketHandler):
    socket_handlers = set()

    def open(self):
        ChatSocketHandler.socket_handlers.add(self)
        print 'websocket'
        send_message('A new user has entered the chat room.')

    def on_close(self):
        ChatSocketHandler.socket_handlers.remove(self)
        print 'websocket close'
        send_message('A user has left the chat room.')

    def on_message(self, message):
        print 'message:'+message
        send_message(message)

 

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

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

socket.io也是个不错的选择,提供了多种传输方案。

 WebSocketMain.swf文件及源码见附件

 

  • 大小: 5 KB
  • 大小: 12.7 KB
  • 大小: 11.9 KB
  • 大小: 18 KB
分享到:
评论

相关推荐

    ie9以下老浏览器不支持HTML5的解决方法

    ie9以下老浏览器不支持HTML5的解决方法

    html5 WebSocket delphi 第二个

    从安卓到苹果,从delphi7-delphi XE8 统统支持,源码!源码!源码!, 有客户端有服务端,这是一个经典的浏览器与delphi的Socket通讯! 谷歌,火狐,IE通通有演示.我编译了一个服务器例子.里面含全部源代码! 注意,解压密码为:1...

    HTML5(webSocket)版五子棋网络对战游戏

    一个完全用HTML5实现的网络...(注:该程序在火狐10.0、11.0版本、谷歌15.0、17.0版本的浏览器上测试过了,其他较老版本的浏览器可能不支持WebSocket,IE内核的浏览器就别去试了,当前微软明确表示不支持WebSocket...)

    webSocketDemo2支持ie浏览器

    这个是可以兼容ie9(ie8没实验过),火狐,谷歌的

    JAVA+WebSocket聊天室(WebSocket示例)

    可惜现在不是所有浏览器都支持HTML5,本例是对TOMCAT7.0.32自带的WebSocket功能展示,一个非常简单的聊天室。 代码说明 1、因为本例只做功能展示,所以使用最为精简的代码,只写了2个类和一个JSP,另外使用到TOMCAT7...

    WebSocket服务器的.NET实现 SuperWebSocket

    作为HTML5的一个重要新特性,WebSocket 规范的目标是在浏览器中实现和服务器端双向通信.双向通信可以拓展浏览器上的应用类型,例如实时的数据推送(股票行情),游戏,聊天/im 等. 现已支持WebSocket的浏览器有: ...

    Java.WebSocket.Programming

    WebSocket是html5新增加的一种通信协议,目前流行的浏览器都支持这个协议,例如Chrome,Safari,Firefox,Opera,IE等等,对该协议支持最早的应该是chrome,从chrome12就已经开始支持,随着协议草案的不断变化,各个...

    java websocket 华视身份证cvr100u,cvr100uc,支持谷歌,火狐浏览器

    令人头大的是华视电子的设备不支持高版本的chrome以及火狐,ie客户不愿意用(支持低版本),网上查了好多资料, 走了不少弯路,在此记录下来,帮助更多的人,也是向自己发现困难相信肯定有办法解决的一股倔强致意。...

    可用的WebSocketDemo,Java编写

    火狐和谷歌可用, ie9不支持, ie10未测试.

    WebSocket服务器的.NET实现 SuperWebSocket的例子

    作为HTML5的一个重要新特性,WebSocket 规范的目标是在浏览器中实现和服务器端双向通信.双向通信可以拓展浏览器上的应用类型,例如实时的数据推送(股票行情),游戏,聊天/im 等. 现已支持WebSocket的浏览器有: ...

    疯狂HTML 5_CSS 3_JavaScript讲义_part1

    HTML 5规范呼之欲出,各浏览器厂商更早已摩拳擦掌,纷纷推出支持HTML 5规范的浏览器:Firefox、Opera、Chrome等浏览器早已很好地支持各种HTML 5规范,微软也宣布IE 9将会更好地支持CSS 3、SVG和HTML 5等新规范,这些...

    疯狂HTML 5_CSS 3_JavaScript讲义_part2

    HTML 5规范呼之欲出,各浏览器厂商更早已摩拳擦掌,纷纷推出支持HTML 5规范的浏览器:Firefox、Opera、Chrome等浏览器早已很好地支持各种HTML 5规范,微软也宣布IE 9将会更好地支持CSS 3、SVG和HTML 5等新规范,这些...

    Nginx实战之反向代理WebSocket的配置实例

    大部分现在的浏览器都支持WebSocket,比如Firefox,IE,Chrome,Safari,Opera,并且越来越多的服务器框架现在也同样支持WebSocket。 WebSocket集群 在实际的生产环境中,要求多个WebSocket服务器必须具有高性能和...

    良田高拍仪摄像头插件兼容chrome含demo可直接使用

    注意:浏览器需要支持HTML5协议,websocket才能正常使用该控件。 1. 提供设备选择 2. 支持设备预览 3. 设置出图格式 4. 设置分辨率 5. 支持拍照功能 6. 获取拍照图像类型文件的BASE64数据 7. 设置纠偏裁边 8. 二代证...

    良田高拍仪浏览器demo兼容chrome

    注意:浏览器需要支持HTML5协议,websocket才能正常使用该控件。 1. 提供设备选择 2. 支持设备预览 3. 设置出图格式 4. 设置分辨率 5. 支持拍照功能 6. 获取拍照图像类型文件的BASE64数据 7. 设置纠偏裁边 8....

    WebSocket部署服务器但外网无法连接的解决方法

    WebSocket是html5新增加的一种通信协议,目前流行的浏览器都支持这个协议,例如Chrome,Safari,Firefox,Opera,IE等等,下面这篇文章主要给大家介绍了关于WebSocket部署服务器但外网无法连接的解决方法,需要的朋友可以...

    海康威视H5播放器开发指南,兼容各种主流浏览器

    海康威视H5播放器开发指南,兼容各种主流浏览器,chrome,IE,火狐。

    利用各种浏览器进行身份证阅读

    一直以来身份证阅读器采用ActiveX控件形式在浏览器端跑,这种方式就只支持IE浏览器和IE内核的浏览器。随着现在很多软件系统对新一代HTML5的热宠以及系统要求使用更快的谷歌Chrome浏览器和火狐Firefox浏览器,绝大...

    HTML5之WebSocket入门3 -通信模型socket.io

     node.js提供了高效的服务端运行环境,但是由于浏览器端对HTML5的支持不一,为了兼容所有浏览器,提供卓越的实时的用户体验,并且为程序员提供客户端与服务端一致的编程体验,于是socket.io诞生。  socket.io设计...

Global site tag (gtag.js) - Google Analytics