我目前正在使用Python构建一个小型套接字服务器,使用WebSocket JavaScript API构建一个基于Web的客户端,并且在发送第一条消息后连接仍然关闭。 我尝试连接到//echo.websocket.org并发送消息,那里没有问题。因此,当我读到错误意味着低级别的实现错误时,我假设它来自我的服务器,我可能是在做握手错误。这是客户端代码:
function init_game(){
socket = new WebSocket('ws://localhost:3003');
//socket = new WebSocket('ws://echo.websocket.org');
setupSocket();
}
function setupSocket(){
socket.onopen = function(){
console.log('Connection open !');
var msg = {cmd: 'hello', params: {}};
var data = JSON.stringify(msg);
console.log('Sending : ' + data);
socket.send(data);
};
socket.onmessage = function(e){
var data = e.data;
console.log('Received : ' + data);
handle(data);
};
socket.onerror = function(e){
console.log('ERROR : ' + e.code + " - " + e.reason);
};
socket.onclose = function(e){
console.log('CONNECTION CLOSED : ' + e.code + " - " + e.reason);
}
}
function handle(data){
//doing stuff
}
window.onload = init_game;
这里是服务器代码:
class ClientThread(threading.Thread):
# Constructor
def __init__(self, conn, id, q):
threading.Thread.__init__(self)
self.conn_ = conn
self.id_ = id
self.name_ = ''
self.q_ = q
self.handshaken_ = True
self.encoded_ = False
# Main loop
def run(self):
raw_data = self.conn_.recv(1024)
if raw_data[:3] == 'GET':
self.handshaken_ = False
self.handshake(raw_data)
while True:
raw_data = self.conn_.recv(1024)
if len(raw_data) == 0:
continue
if self.handshaken_:
if self.encoded_:
raw_data = self.decode(raw_data).decode('utf-8')
try:
data = json.loads(raw_data)
cmd = data['cmd']
params = data['params']
self.handle(cmd, params)
except ValueError, e:
print 'Data received was not JSON'
else:
print 'Received something but Handshake is not done yet... Something is going wrong.'
# Decode encoded message received frmo the client
def decode(self, data):
frame = bytearray(data)
length = frame[1] & 127
indexFirstMask = 2
if length == 126:
indexFirstMask = 4
elif length == 127:
indexFirstMask = 10
indexFirstDataByte = indexFirstMask + 4
mask = frame[indexFirstMask:indexFirstDataByte]
i = indexFirstDataByte
j = 0
decoded = []
while i < len(frame):
decoded.append(frame[i] ^ mask[j%4])
i += 1
j += 1
return "".join(chr(byte) for byte in decoded)
# Performs handshake protocole in case it's needed
def handshake(self, get):
websocket_answer = (
'HTTP/1.1 101 Switching Protocols',
'Upgrade: websocket',
'Connection: Upgrade',
'Sec-WebSocket-Accept: {key}\r\n\r\n',
)
GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
raw_key = re.search('Sec-WebSocket-Key:\s+(.*?)[\n\r]+', get)
if raw_key != None:
# Create Handshake answer...
key = raw_key.groups()[0].strip()
handshake_key = b64encode(sha1(key + GUID).digest())
handshake = '\r\n'.join(websocket_answer).format(key=handshake_key)
# And send it to the client
self.conn_.send(handshake)
self.handshaken_ = True
self.encoded_ = True
else:
print 'No key found during Handshake.'
self.disconnect()
# Handle JSON commands send by the client
def handle(self, cmd, params):
# doing stuff
def disconnect(self):
print 'Disconnecting.'
pass
class MainServer(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.HOST = ''
self.PORT = 3003
self.socket_ = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
self.socket_.bind((self.HOST, self.PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
self.clients_ = {1: Player(1), 2: Player(2)}
self.q_ = Queue()
def run(self):
self.socket_.listen(10)
nb_player = 0
new_id = 1
while nb_player < 2:
conn, addr = self.socket_.accept()
print 'A new player connected with ' + addr[0] + ':' + str(addr[1])
self.clients_[new_id].conn = conn
th = ClientThread(conn, new_id, self.q_)
th.start()
new_id += 1
nb_player += 1
while True:
data = self.q_.get(block=True)
self.handle(data['cmd'], data['params'])
def handle(self, cmd, params):
# doing stuff
if __name__ == '__main__':
serv = MainServer()
serv.start()
如果您需要任何其他信息,请告诉我。 谢谢 ! 罗宾