websocket

  • 介绍
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]
  • javascript客户端
[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]
  • Python编写的服务端
模块安装: 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

转载于:https://my.oschina.net/surenpi/blog/605367

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值