参考资料:
Websocket协议之握手连接:http://www.tuicool.com/articles/fyAZRn
用Python实现一个简单的WebSocket服器:http://blog.csdn.net/jiht594/article/details/43764941:http://blog.csdn.net/jiht594/article/details/43764941
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
客户端比较容易实现,quickcocos3.3版本,使用cocos封装的 websocket,建立连接的lua代码:
function onOpen_( ... )
print("websock is open")
end
function onMessage_( message )
print("websock is onMessage_",message)
end
function onClose_( ... )
print("websock is onClose_")
end
function onError_( ... )
print("websock is onError_")
end
socket = cc.WebSocket:create("ws://127.0.0.1:9085/")
if socket then
socket:registerScriptHandler(onOpen_, cc.WEBSOCKET_OPEN)
socket:registerScriptHandler(onMessage_, cc.WEBSOCKET_MESSAGE)
socket:registerScriptHandler(onClose_, cc.WEBSOCKET_CLOSE)
socket:registerScriptHandler(onError_, cc.WEBSOCKET_ERROR)
end
python写的服务器代码:
#!/usr/bin/python
#coding=utf-8
# Filename: server.py
import socket,time
import threading
import hashlib
import struct
from base64 import b64encode, b64decode
sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sk.bind(("127.0.0.1",9085))
sk.listen(5)
def tcplink(sock,addr):
print 'Accept new connection from %s:%s...' % addr
# sock.send('Welcome!')
notShake = True
while True:
data = sock.recv(1024)
print data
buffer = ''
if notShake:
headers = {}
buffer += bytes.decode(data)
if buffer.find('\r\n\r\n') != -1:
notShake = False
header, data1 = buffer.split('\r\n\r\n', 1)
for line in header.split("\r\n")[1:]:
key, value = line.split(": ", 1)
headers[key] = value
headers["Location"] = ("ws://%s%s" %(headers["Host"], '/'))
GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
key = headers['Sec-WebSocket-Key']
token = b64encode(hashlib.sha1(str.encode(str(key + GUID))).digest())
handshake="HTTP/1.1 101 Switching Protocols\r\n"\
"Upgrade: websocket\r\n"\
"Connection: Upgrade\r\n"\
"Sec-WebSocket-Accept: "+bytes.decode(token)+"\r\n"\
"WebSocket-Origin: "+str(headers["Origin"])+"\r\n"\
"WebSocket-Location: "+str(headers["Location"])+"\r\n\r\n"
print handshake
sock.send(str.encode(str(handshake)))
else:
time.sleep(1)
if data == 'exit' or not data:
# sock.close()
# print 'Connection from%s:%s Closed' % addr
break
# else:
sock.send('Hello,%s' % data)
if __name__ == "__main__":
while True:
sock,addr = sk.accept()
t = threading.Thread(target=tcplink,args=(sock,addr))
t.start()
# sk.sendall(bytes("Hello world",encoding="utf-8"))
服务端实现的要点:
1.使用socket库创建连接,绑定地址和端口
sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sk.bind(("127.0.0.1",9085))
sk.listen(5)
2.响应握手协议
headers = {}
buffer += bytes.decode(data)
if buffer.find('\r\n\r\n') != -1:
notShake = False
header, data1 = buffer.split('\r\n\r\n', 1)
for line in header.split("\r\n")[1:]:
key, value = line.split(": ", 1)
headers[key] = value
headers["Location"] = ("ws://%s%s" %(headers["Host"], '/'))
GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
key = headers['Sec-WebSocket-Key']
token = b64encode(hashlib.sha1(str.encode(str(key + GUID))).digest())
handshake="HTTP/1.1 101 Switching Protocols\r\n"\
"Upgrade: websocket\r\n"\
"Connection: Upgrade\r\n"\
"Sec-WebSocket-Accept: "+bytes.decode(token)+"\r\n"\
"WebSocket-Origin: "+str(headers["Origin"])+"\r\n"\
"WebSocket-Location: "+str(headers["Location"])+"\r\n\r\n"
print handshake
sock.send(str.encode(str(handshake)))
关键点是对客户端传过来的key做处理生成token,并回传"Sec-WebSocket-Accept: "+token,完成握手
data = sock.recv(1024)
header, data1 = buffer.split('\r\n\r\n', 1)
for line in header.split("\r\n")[1:]:
key, value = line.split(": ", 1)
headers[key] = value
key = headers['Sec-WebSocket-Key']
token = b64encode(hashlib.sha1(str.encode(str(key + GUID))).digest())