让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. 把书《CUDA By Example an Introduction to General Purpose GPU Programming》读薄

    鉴于自己的毕设需要使用GPU CUDA这项技术,想找一本入门的教材,选择了Jason Sanders等所著的书<CUDA By Example an Introduction to Genera ...

  2. @Mapper 和 @MapperScan 区别

    1.@Mapper : 为了使接口被其他类引用,需要使用@Mapper注解,这种方式要求每一个mapper类都需要添加此注解,麻烦. package com.example.demo.dao; imp ...

  3. 【转】Flash AS3.0 中的自定义事件

    原文 http://www.cnblogs.com/acpp/archive/2010/10/19/1855670.html package { import flash.events.Event; ...

  4. 【Henu ACM Round#14 B】Duff in Love

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 让你在n的因子里面找一个最大的数字x 且x的因子全都不是完全平方数(y^2,y>1) O(sqrt(n))找出n的所有因子. ...

  5. CS224d lecture 9札记

    欢迎转载.转载注明出处: http://blog.csdn.net/neighborhoodguo/article/details/47193885 近期几课的内容不是非常难.还有我的理解能力有所提高 ...

  6. Reuse Is About People and Education, Not Just Architecture

     Reuse Is About People and Education, Not Just Architecture Jeremy Meyer you MigHT AdopT THE AppRoA ...

  7. ios in-house 公布整个过程(startssl认证)

    首先大体说一下步骤: 1.申请苹果enterprise 账号 为应用生成app id,provision profile等 详见:http://www.th7.cn/Program/IOS/20131 ...

  8. git 版本管理工具说明

    $ git init                 (初始化本地仓库,会生成.git 文件夹  .git 文件夹里存储了所有的版本信息.标记等内容) $ git add .              ...

  9. C# 使用 X.509 v.3 证书的方法。

    C# 使用 X.509 v.3 证书的方法. public static void Main()    { // The path to the certificate.        string ...

  10. 关于html(meta的常用的用法)

    http://www.haorooms.com/post/html_meta_ds