html5 websocket连接到python
Posted
技术标签:
【中文标题】html5 websocket连接到python【英文标题】:html5 websocket connecting to python 【发布时间】:2013-08-14 19:15:36 【问题描述】:我正在尝试将 html5 websocket 连接到 python。我有两个文件:
1. index.html
<script>
window.onload = function()
var connection = new WebSocket("ws://localhost:9876/");
connection.onopen = function ()
connection.send('Ping');
;
connection.onerror = function (error)
console.log('WebSocket Error ' + error);
;
connection.onmessage = function (e)
console.log('Server: ' + e.data);
;
;
</script>
2。 server.py
import socket
HOST = ''
PORT = 9876
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(5)
conn, addr = s.accept()
print 'Connected by', addr
conn.send("Hello")
while 1:
data = conn.recv(4096)
print data
if not data: break
conn.sendall(data)
conn.close()
启动 server.py 后,它会一直运行,直到我在浏览器中打开 index.html。当我这样做时,我会在控制台上显示以下内容:
到 'ws://localhost:9876/' 的 WebSocket 连接失败: WebSocket 错误 [对象事件]
但是,在另一边(server.py)我得到:
Connected by('127.0.0.1', 55460)GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: localhost:9876
Origin: null
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: WP0GtT0hrdX1bKa0DepOHQ==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
问我的代码有什么问题?我应该如何修改它以便在它们之间进行生物通信? 我正在寻找这样的东西:
if data == 'kill': conn.close()
重要修改
如果我将 index.html 中的 WebSocket("ws://localhost:9876/")
更改为 WebSocket("ws://html5rocks.websocket.org/echo")
,它就会起作用。我想这意味着问题出在 server.py 端
线索#2
如果我在html中写WebSocket("ws://localhost/:9876")
,python代码无法继续conn, addr = s.accept()
这一行
【问题讨论】:
当 server.py 运行时,当你远程登录到套接字时会发生什么?telnet localhost 9876
@Mike 对不起,不知道在哪里输入上面的代码?
@gen tellnet 是一个 shell(命令提示符)命令,而不是代码。它只是尝试与任何地址建立连接,试一试并上传结果。
@enginefree 我的意思是命令而不是代码,但是我的 cmd 无法识别命令 'telnet'
您可能在 Windows 上。在这种情况下你可以试试这个,fettesps.com/windows-7-enable-telnet
【参考方案1】:
您没有响应标头。 试试看,
server.py
import socket, hashlib, base64, threading
class PyWSock:
MAGIC = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
HSHAKE_RESP = "HTTP/1.1 101 Switching Protocols\r\n" + \
"Upgrade: websocket\r\n" + \
"Connection: Upgrade\r\n" + \
"Sec-WebSocket-Accept: %s\r\n" + \
"\r\n"
LOCK = threading.Lock()
clients = []
def recv_data (self, client):
# as a simple server, we expect to receive:
# - all data at one go and one frame
# - one frame at a time
# - text protocol
# - no ping pong messages
data = bytearray(client.recv(512))
if(len(data) < 6):
raise Exception("Error reading data")
# FIN bit must be set to indicate end of frame
assert(0x1 == (0xFF & data[0]) >> 7)
# data must be a text frame
# 0x8 (close connection) is handled with assertion failure
assert(0x1 == (0xF & data[0]))
# assert that data is masked
assert(0x1 == (0xFF & data[1]) >> 7)
datalen = (0x7F & data[1])
#print("received data len %d" %(datalen,))
str_data = ''
if(datalen > 0):
mask_key = data[2:6]
masked_data = data[6:(6+datalen)]
unmasked_data = [masked_data[i] ^ mask_key[i%4] for i in range(len(masked_data))]
str_data = str(bytearray(unmasked_data))
return str_data
def broadcast_resp(self, data):
# 1st byte: fin bit set. text frame bits set.
# 2nd byte: no mask. length set in 1 byte.
resp = bytearray([0b10000001, len(data)])
# append the data bytes
for d in bytearray(data):
resp.append(d)
self.LOCK.acquire()
for client in self.clients:
try:
client.send(resp)
except:
print("error sending to a client")
self.LOCK.release()
def parse_headers (self, data):
headers =
lines = data.splitlines()
for l in lines:
parts = l.split(": ", 1)
if len(parts) == 2:
headers[parts[0]] = parts[1]
headers['code'] = lines[len(lines) - 1]
return headers
def handshake (self, client):
print('Handshaking...')
data = client.recv(2048)
headers = self.parse_headers(data)
print('Got headers:')
for k, v in headers.iteritems():
print k, ':', v
key = headers['Sec-WebSocket-Key']
resp_data = self.HSHAKE_RESP % ((base64.b64encode(hashlib.sha1(key+self.MAGIC).digest()),))
print('Response: [%s]' % (resp_data,))
return client.send(resp_data)
def handle_client (self, client, addr):
self.handshake(client)
try:
while 1:
data = self.recv_data(client)
print("received [%s]" % (data,))
self.broadcast_resp(data)
except Exception as e:
print("Exception %s" % (str(e)))
print('Client closed: ' + str(addr))
self.LOCK.acquire()
self.clients.remove(client)
self.LOCK.release()
client.close()
def start_server (self, port):
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', port))
s.listen(5)
while(1):
print ('Waiting for connection...')
conn, addr = s.accept()
print ('Connection from: ' + str(addr))
threading.Thread(target = self.handle_client, args = (conn, addr)).start()
self.LOCK.acquire()
self.clients.append(conn)
self.LOCK.release()
ws = PyWSock()
ws.start_server(9876)
link
我认为最小的 server.py
import socket,hashlib,base64
MAGIC = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
HSHAKE_RESP = "HTTP/1.1 101 Switching Protocols\r\n" + \
"Upgrade: websocket\r\n" + \
"Connection: Upgrade\r\n" + \
"Sec-WebSocket-Accept: %s\r\n" + \
"\r\n"
HOST = ''
PORT = 9876
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(5)
conn, addr = s.accept()
print 'Connected by', addr
data = conn.recv(4096)
headers =
lines = data.splitlines()
for l in lines:
parts = l.split(": ", 1)
if len(parts) == 2:
headers[parts[0]] = parts[1]
headers['code'] = lines[len(lines) - 1]
key = headers['Sec-WebSocket-Key']
resp_data = HSHAKE_RESP % ((base64.b64encode(hashlib.sha1(key+MAGIC).digest()),))
conn.send(resp_data)
while 1:
data = conn.recv(4096)
if not data:
break
databyte = bytearray(data)
datalen = (0x7F & databyte[1])
str_data = ''
if(datalen > 0):
mask_key = databyte[2:6]
masked_data = databyte[6:(6+datalen)]
unmasked_data = [masked_data[i] ^ mask_key[i%4] for i in range(len(masked_data))]
str_data = str(bytearray(unmasked_data))
print str_data
resp = bytearray([0b10000001, len(str_data)])
for d in bytearray(str_data):
resp.append(d)
conn.sendall(resp)
conn.close()
一次运行。因为不是线程。
【讨论】:
你能告诉我是什么使它工作,我的原始代码中没有吗? websocket 正在运行请求标头和响应标头。您的服务器代码没有响应标头。 对不起,你能解释一下什么是响应头吗? 可以看到 "print('Response: [%s]' % (resp_data,))", "HTTP/1.1 101 Switching Protocols\r\n" + \ "Upgrade: websocket\r \n" + \ "连接:升级\r\n" + \ "Sec-WebSocket-Accept: %s\r\n" + \ "\r\n" 实际上,由于我无法理解您的代码,因此我想找到最简单的仍然有效的代码。你能告诉我哪些部分是最重要的吗?例如,我不需要加密。以上是关于html5 websocket连接到python的主要内容,如果未能解决你的问题,请参考以下文章
HTML5 Websocket 连接到 Windows .NET 服务器,但没有收到 WebSocket.onopen 通知。
从浏览器请求连接到 C# 程序后,WebSocket 没有响应
WebSocket 不会连接到 127.0.0.1 / localhost 以外的任何东西