def _handShake(self, hostAddress, portNumber):
CRLF = "\r\n"
hostAddressChunks = hostAddress.split('.') # <randomString>.iot.<region>.amazonaws.com
region = hostAddressChunks[2] # XXXX.<region>.beta
signedURL = self._sigV4Handler.createWebsocketEndpoint(hostAddress, portNumber, region, "GET", "iotdata", "/mqtt")
if signedURL == "":
raise wssNoKeyInEnvironmentError()
# Now we got a signedURL
path = signedURL[signedURL.index("/mqtt"):]
# Assemble HTTP request headers
Method = "GET " + path + " HTTP/1.1" + CRLF
Host = "Host: " + hostAddress + CRLF
Connection = "Connection: " + "Upgrade" + CRLF
Upgrade = "Upgrade: " + "websocket" + CRLF
SecWebSocketVersion = "Sec-WebSocket-Version: " + "13" + CRLF
rawSecWebSocketKey = self._generateWSSKey()
SecWebSocketKey = "sec-websocket-key: " + rawSecWebSocketKey + CRLF # Should be randomly generated...
SecWebSocketProtocol = "Sec-WebSocket-Protocol: " + "mqttv3.1" + CRLF
SecWebSocketExtensions = "Sec-WebSocket-Extensions: " + "permessage-deflate; client_max_window_bits" + CRLF
# Send the HTTP request
self._sslSocket.write(Method + Host + Connection + Upgrade + SecWebSocketVersion + SecWebSocketProtocol + SecWebSocketExtensions + SecWebSocketKey + CRLF)
# Read it back (Non-blocking socket)
# Do we need a timeout here?
wssHandshakeResponse = ""
while len(wssHandshakeResponse) == 0:
try:
wssHandshakeResponse += self._sslSocket.read(1024) # Response is always less than 1024 bytes
except socket.error as err:
if err.errno == ssl.SSL_ERROR_WANT_READ or err.errno == ssl.SSL_ERROR_WANT_WRITE:
pass
# Verify response
if not self._verifyWSSResponse(wssHandshakeResponse, rawSecWebSocketKey):
raise wssHandShakeError()
else:
pass
# Used to create a single wss frame
# Assume that the maximum length of a MQTT packet never exceeds the maximum length
# for a wss frame. Therefore, the FIN bit for the encoded frame will always be 1.
# Frames are encoded as BINARY frames.
评论列表
文章目录