websocket可是使javascript来连接一个socket,这样的话,可以建立一个长连接,实现“推送”效果。 本文中介绍了如何用Python来实现websocket的服务端,以及使用javascript来作为客户端与之通信,包括了消息的发送和接收。
js发送的协议内容: [codesyntax lang="div"]
GET / HTTP/1.1
Host: 10.0.32.39:9000
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://localhost
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
Cookie: csrftoken=jk1AqWVZNJrRp0nI1lLNLNdChAnWGnZq
Sec-WebSocket-Key: 43FqzAWksH8aPcp2Kko4oA==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
[/codesyntax] 服务器响应的数据包格式: [codesyntax lang="div"]
HTTP/1.1 101 Switching Protocols
Upgrade:websocket
Connection: Upgrade
Sec-WebSocket-Accept: CVx5sEUL61AJLhMneOxyXHEe8ok=
WebSocket-Location: ws://0.0.0.0:9000/chat
WebSocket-Protocol:chat
[/codesyntax]
[codesyntax lang="javascript"]
<html> <head>
<script type="text/javascript">
var socket = new WebSocket('ws://10.0.32.39:9000');
socket.onopen = function(e)
{
console.log('onopen : ' + e);
}
socket.onclose = function(e)
{
console.log('onclose : ' + e + '; length : ' + arguments.length);
}
socket.onmessage = function(e)
{
console.log('onmessage : ' + e + '; length : ' + arguments.length);
console.log('data : ' + e.data);
socket.send('suren');
}
</script>
</head> <body> </body> </html>
[/codesyntax]
模块安装: pip install simplejson pip install base64 pip install hashlib 下面是websocket的服务器的实现代码: [codesyntax lang="python"]
__author__ = 'suren'
import simplejson
import socket
import sys
import base64
import hashlib
import time
HOST = '10.0.32.39'
PORT = 9000
MAGIC_STRING = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
HANDSHAKE_STRING = "HTTP/1.1 101 Switching Protocols\r\n" \
"Upgrade:WebSocket\r\n" \
"Connection: Upgrade\r\n" \
"Sec-WebSocket-Accept: {1}\r\n" \
"WebSocket-Location: ws://{2}/chat\r\n" \
"WebSocket-Protocol:chat\r\n\r\n"
def parse_data(msg):
v = ord(msg[1]) & 0x7f
if v == 0x7e:
p = 4
elif v == 0x7f:
p = 10
else:
p = 2
mask = msg[p:p+4]
data = msg[p+4:]
return ''.join([chr(ord(v) ^ ord(mask[k%4])) for k, v in enumerate(data)])
def start():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
sock.bind((HOST, PORT))
sock.listen(100)
except Exception as e:
print('bind error')
print(e)
sys.exit()
while True:
conn, add = sock.accept()
try:
handshake(conn)
finally:
print('finally')
conn.close()
sock.close()
pass
def handshake(conn):
headers = {}
shake = conn.recv(1024)
print shake
if not len(shake):
print('len error')
return False
header, data = shake.split('\r\n\r\n', 1)
for line in header.split('\r\n')[1:]:
key, value = line.split(': ', 1)
headers[key] = value
if 'Sec-WebSocket-Key' not in headers:
print('this is not websocket, client close.')
print headers
conn.close()
return False
sec_key = headers['Sec-WebSocket-Key']
res_key = base64.b64encode(hashlib.sha1(sec_key + MAGIC_STRING).digest())
str_handshke = HANDSHAKE_STRING.replace('{1}', res_key).replace('{2}', HOST + ":" + str(PORT))
print str_handshke
conn.send(str_handshke)
time.sleep(1)
conn.send('%c%c%s' % (0x81, 5, 'suren'))
msg = conn.recv(1024)
msg = parse_data(msg)
print('msg : ' + msg)
time.sleep(1)
conn.send('%c%c%s' % (0x81, 5, 'suren'))
msg = conn.recv(1024)
msg = parse_data(msg)
print('msg : ' + msg)
time.sleep(1)
conn.send('%c%c%s' % (0x81, 5, 'suren'))
msg = conn.recv(1024)
msg = parse_data(msg)
print('msg : ' + msg)
return True
pass
if __name__ == '__main__':
try:
start()
except Exception as e:
print(e)
[/codesyntax]
http://www.jb51.net/article/51516.htm
Python之socket
The WebSocket Protocol http://datatracker.ietf.org/doc/rfc6455/?include_text=1
在安卓中使用websocket http://my.oschina.net/1123581321/blog/333031