#!/usr/bin/env python
import asyncore
import socket
import struct
import time
import hashlib
class WebSocketConnection(asyncore.dispatcher_with_send):
def __init__(self, conn, server):
asyncore.dispatcher_with_send.__init__(self, conn)
self.server = server
self.server.sessions.append(self)
self.readystate = "connecting"
self.buffer = ""
def handle_read(self):
data = self.recv(1024)
self.buffer += data
if self.readystate == "connecting":
self.parse_connecting()
elif self.readystate == "open":
self.parse_frametype()
def handle_close(self):
self.server.sessions.remove(self)
self.close()
def parse_connecting(self):
header_end = self.buffer.find("\r\n\r\n")
if header_end == -1:
return
else:
header = self.buffer[:header_end]
# remove header and four bytes of line endings from buffer
self.buffer = self.buffer[header_end+4:]
header_lines = header.split("\r\n")
headers = {}
# validate HTTP request and construct location
method, path, protocol = header_lines[0].split(" ")
if method != "GET" or protocol != "HTTP/1.1" or path[0] != "/":
self.terminate()
return
# parse headers
for line in header_lines[1:]:
key, value = line.split(": ")
headers[key] = value
headers["Location"] = "ws://" + headers["Host"] + path
self.readystate = "open"
self.handler = self.server.handlers.get(path, None)(self)
if "Sec-WebSocket-Key1" in headers.keys():
self.send_server_handshake_76(headers)
else:
self.send_server_handshake_75(headers)
def terminate(self):
self.ready_state = "closed"
self.close()
def send_server_handshake_76(self, headers):
"""
Send the WebSocket Protocol v.76 handshake response
"""
key1 = headers["Sec-WebSocket-Key1"]
key2 = headers["Sec-WebSocket-Key2"]
# read additional 8 bytes from buffer
key3, self.buffer = self.buffer[:8], self.buffer[8:]
response_token = self.calculate_key(key1, key2, key3)
# write out response headers
self.send_bytes("HTTP/1.1 101 Web Socket Protocol Handshake\r\n")
self.send_bytes("Upgrade: WebSocket\r\n")
self.send_bytes("Connection: Upgrade\r\n")
self.send_bytes("Sec-WebSocket-Origin: %s\r\n" % headers["Origin"])
self.send_bytes("Sec-WebSocket-Location: %s\r\n" % headers["Location"])
if "Sec-WebSocket-Protocol" in headers:
protocol = headers["Sec-WebSocket-Protocol"]
self.send_bytes("Sec-WebSocket-Protocol: %s\r\n" % protocol)
self.send_bytes("\r\n")
# write out hashed response token
self.send_bytes(response_token)
def calculate_key(self, key1, key2, key3):
# parse keys 1 and 2 by extracting numerical characters
num1 = int("".join([digit for digit in list(key1) if digit.isdigit()]))
spaces1 = len([char for char in list(key1) if char == " "])
num2 = int("".join([digit for digit in list(key2) if digit.isdigit()]))
spaces2 = len([char for char in list(key2) if char == " "])
combined = struct.pack(">II", num1/spaces1, num2/spaces2) + key3
# md5 sum the combined bytes
return hashlib.md5(combined).digest()
def send_server_handshake_75(self, headers):
"""
Send the WebSocket Protocol v.75 handshake response
"""
self.send_bytes("HTTP/1.1 101 Web Socket Protocol Handshake\r\n")
self.send_bytes("Upgrade: WebSocket\r\n")
self.send_bytes("Connection: Upgrade\r\n")
self.send_bytes("WebSocket-Origin: %s\r\n" % headers["Origin"])
self.send_bytes("WebSocket-Location: %s\r\n" % headers["Location"])
if "Protocol" in headers:
self.send_bytes("WebSocket-Protocol: %s\r\n" % headers["Protocol"])
self.send_bytes("\r\n")
def parse_frametype(self):
while len(self.buffer):
type_byte = self.buffer[0]
if type_byte == "\x00":
if not self.parse_textframe():
return
def parse_textframe(self):
terminator_index = self.buffer.find("\xFF")
if terminator_index != -1:
frame = self.buffer[1:terminator_index]
self.buffer = self.buffer[terminator_index+1:]
s = frame.decode("UTF8")
self.handler.dispatch(s)
return True
else:
# incomplete frame
return false
def send(self, s):
if self.readystate == "open":
self.send_bytes("\x00")
self.send_bytes(s.encode("UTF8"))
self.send_bytes("\xFF")
def send_bytes(self, bytes):
asyncore.dispatcher_with_send.send(self, bytes)
class EchoHandler(object):
"""
The EchoHandler repeats each incoming string to the same Web Socket.
"""
def __init__(self, conn):
self.conn = conn
def dispatch(self, data):
self.conn.send("echo: " + data)
class WebSocketServer(asyncore.dispatcher):
def __init__(self, port=80, handlers=None):
asyncore.dispatcher.__init__(self)
self.handlers = handlers
self.sessions = []
self.port = port
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind(("", port))
self.listen(5)
def handle_accept(self):
conn, addr = self.accept()
session = WebSocketConnection(conn, self)
if __name__ == "__main__":
print "Starting WebSocket Server"
WebSocketServer(port=8080, handlers={"/echo": EchoHandler})
asyncore.loop()
没有合适的资源?快使用搜索试试~ 我知道了~
《HTML5高级程序设计》(源代码)
共92个文件
html:52个
css:12个
js:6个
5星 · 超过95%的资源 需积分: 12 503 下载量 79 浏览量
2011-05-16
16:10:54
上传
评论 11
收藏 5.41MB RAR 举报
温馨提示
HTML5高级程序设计(随书源码) 作者:(荷)柳伯斯,(美)阿伯斯,(美)萨姆, 李杰,柳靖,刘淼 译 本书首先介绍了HTML5的历史背景、新的语义标签及与以往HTML版本相比的根本变化,同时揭示了HTML5背后的设计原理.从第2章起,分别围绕构建令人神往的富Web应用,逐一讨论了HTML5的Canvas、Geolocation、Communication、WebSocket、Forms、Web Workers、Storage等APⅡ的使用,辅以直观明了的客户端和服务器端示例代码,让开发人员能够迅速理解和掌握新一代Web标准所涵盖的核心技术。本书最后探索了离线Web应用并展望了HTML5未来的发展前景。 本书面向有一定经验的Web应用开发人员,对HTML5及未来Web应用技术发展抱有浓厚兴趣的读者也可以学习参考。 注: 源码中的av部分缺少Intermission-Walk-in.ogv和Intermission-Walk-in_512kb.mp4这两个文件,因为文件太大了。
资源推荐
资源详情
资源评论
收起资源包目录
prohtml5.rar (92个子文件)
prohtml5
communication
start-server.sh 87B
postMessagePortal.html 2KB
styles.css 4KB
CORSServer.py 1KB
postMessageWidget.html 1KB
crossOriginUpload.html 3KB
forms
happy-trails-rc.gif 6KB
signup.html 5KB
passwordMatch.html 2KB
patternList.html 2KB
html5.css 2KB
offline
log.js 210B
tracker.html 579B
tracker.js 1KB
offline.js 2KB
html5.css 2KB
tracker.manifest 119B
style.css 154B
workers
start-server.sh 87B
blur.js 1KB
blur.html 4KB
blurWorker.js 1KB
echo.html 1KB
example2.png 523KB
styles.css 4KB
example.png 37KB
echoWorker.js 137B
canvas
bark.jpg 25KB
trails-curve.html 2KB
trails-final.html 3KB
trails-scaling.html 3KB
trails-shadow.html 4KB
trails-pattern.html 3KB
trails-fillRect.html 2KB
trails-text.html 4KB
gravel.jpg 4KB
mapbg.jpg 5KB
trails-transform.html 4KB
trails-fillStyle.html 1KB
styles.css 4KB
trails-image.html 2KB
heatmap.html 2KB
trails-gradient.html 3KB
trails-diagonalTranslate.html 921B
trails-closedPath.html 1KB
trails-diagonal.html 727B
trails-strokeStyle.html 1KB
intro
querySelectorAll.html 2KB
sample.html 2KB
html5.css 2KB
querySelector.html 1KB
storage
testQuota.html 10KB
start-server.sh 90B
session.html 569B
racerBroadcast.html 3KB
browser-test.html 1KB
storageInsert.html 544B
sql.html 2KB
happy-trails-rc.gif 6KB
index.html 5KB
lake-tahoe.JPG 16KB
signup.html 5KB
styles.css 4KB
storageLog.html 721B
html5.css 2KB
about.html 6KB
av
backgroundMusic.html 297B
audio_multisource.html 291B
audioCue.html 715B
audio_type.html 341B
johann_sebastian_bach_air.mp3 2.8MB
arrp.wav 2KB
audio.html 381B
johann_sebastian_bach_air.ogg 2.13MB
styles.css 4KB
mouseoverVideo.html 485B
缺少Intermission-Walk-in.ogv因为文件太大 0B
缺少Intermission-Walk-in_512kb.mp4因为文件太大 0B
videoTimeline.html 4KB
audio_no_control.html 341B
audio_simple.html 227B
websocket
start-server.sh 87B
websocket.py 6KB
tracker.html 4KB
broadcast.py 550B
styles.css 5KB
broadcast.html 1KB
websocket.html 961B
geolocation
status-info.png 1KB
geolocation.html 2KB
styles.css 4KB
odometer.html 4KB
共 92 条
- 1
feiyinglm
- 粉丝: 1
- 资源: 8
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
- 3
- 4
- 5
- 6
前往页