让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的原理。

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

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='width: 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>\0'''
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

让ie6 7 8 9支持原生html5 websocket的更多相关文章

  1. Practical Node.js (2018版) 第9章: 使用WebSocket建立实时程序,原生的WebSocket使用介绍,Socket.IO的基本使用介绍。

    Real-Time Apps with WebSocket, Socket.IO, and DerbyJS 实时程序的使用变得越来越广泛,如传统的交易,游戏,社交,开发工具DevOps tools, ...

  2. 如何让低版本的IE浏览器(IE6/IE7/IE8)支持HTML5 header等新标签

    html5提供的一些新标签(article,aside,dialog,footer,header,section,footer,nav,figure,menu)使用起来非常的方便,但是低版本的IE浏览 ...

  3. IE(IE6/IE7/IE8)支持HTML5标签

    让IE(ie6/ie7/ie8)支持HTML5元素,我们需要在HTML头部添加以下JavaScript,这是一个简单的document.createElement声明,利用条件注释针对IE来调用这个j ...

  4. IE(IE6/IE7/IE8)支持HTML5标签--20150216

    让IE(ie6/ie7/ie8)支持HTML5元素,我们需要在HTML头部添加以下JavaScript,这是一个简单的document.createElement声明,利用条件注释针对IE来调用这个j ...

  5. 解决IE6/IE7/IE8不支持before,after问题

    对从事web开发的朋友来讲,低版本的IE永远是一个痛点,不支持最新技术(如css3,html5). 在现在web开发中使用图标字体已经很广泛,如Font Awesome,Bootstrap等,字体图片 ...

  6. 让IE6/IE7/IE8浏览器支持CSS3属性

    让IE6/IE7/IE8浏览器支持CSS3属性 一.下载 您可以狠狠地点击这里:ie-css3.htc,这个玩意儿是让IE浏览器支持CSS3表现的关键东东. 二.上面的是什么东西 首先说说.htc文件 ...

  7. 原生HTML5 input type=file按钮UI自定义

    原生<input type="file" name="file" />长得太丑 提升一下颜值 实现方案一.设置input[type=file]透明度 ...

  8. 隐藏原生html5 video controls

    隐藏原生html5 video controls 凤凰视频焦点项目mobile html5播放器测试时bug,由于没有用原生的controls而是自己写的custom controls,虽然设置了co ...

  9. MVC 插件化框架支持原生MVC的Area和路由特性

    .NET MVC 插件化框架支持原生MVC的Area和路由特性 前面开放的源码只是简单的Plugin的实现,支持了插件的热插拔,最近晚上偶然想到,原生的MVC提供Areas和RouteAtrribut ...

随机推荐

  1. 【 正确使用vim编辑器的姿势】

    vi:可视化接口(Visual Interface) vim:是vi的增强版(vi iMprove) vi编辑器是所有Unix及Linux系统下标准的编辑器,他就相当于windows系统中的记事本一样 ...

  2. CentOS7 PXE安装批量安装操作系统

    1.安装相关软件 yum -y install tftp-server httpd dhcp syslinux 2.配置DHCP cp /usr/share/doc/dhcp-4.2.5/dhcpd. ...

  3. 洛谷 P1324 矩形分割

    P1324 矩形分割 题目描述 出于某些方面的需求,我们要把一块N×M的木板切成一个个1×1的小方块. 对于一块木板,我们只能从某条横线或者某条竖线(要在方格线上),而且这木板是不均匀的,从不同的线切 ...

  4. Git版本号控制

        Git是分布式版本号控制系统.与SVN类似的集中化版本号控制系统相比.集中化版本号控制系统尽管可以令多个团队成员一起协作开发,但有时假设中央server宕机的话,谁也无法在宕机期间提交更新和协 ...

  5. ios学习之旅------玩转结构体

    1.全局变量和局部变量 局部变量:     概念:定义函数内部变量     定义格式:变量类型 变量名称;     作用域:从定义那一行開始到所在代码块结束     生命周期:从代码运行到定义的哪一行 ...

  6. Android学习笔记进阶20 之得到图片的缩略图

    <1>简介 之前往往是通过Bitmap.Drawable和Canvas配合完成,需要写一系列繁杂的逻辑去缩小原有图片,从而得到缩略图. 现在我给大家介绍一种比较简单的方法:(网上有) 在A ...

  7. php intval函数

    php intval函数 作用 intval — 获取变量的整数值 使用实例 <?php echo intval('-42'); // -42 ?> 相似函数 boolval() - 获取 ...

  8. class的写法

    java中class的写法:1.public class xxx{}2.非public类:public class A{}public class B{}必须保证一个其中一个类名是public并与ja ...

  9. area热点区域

    <area>标记:主要用于图像地图,通过该标记可以在图像地图中设定作用区域(又称为热点),这样当用户的鼠标移到指定的作用区域点击时,会自动链接到预先设定好的页面.其基本语法结构如下: &l ...

  10. 关于使用strtok的一个小问题

    今天在弄一下啊小小程序的时候.报错,出现了问题.先看代码 int main(int argc, char* argv[]) { char *filename = "interface_ips ...