导航:首页 > 编程语言 > pythonwebsocket接口

pythonwebsocket接口

发布时间:2023-09-25 17:44:31

1. 使用python Websockets库建立WebSocket客户端链接

使用with语句进行connect连接后的上下文自动管理,当hello协程退出时,自动关闭该WebSocket连接。

不同于基本示例的是,connect函数中需要指定ssl参数做戚的内容

可以看到与基本示例不同的地方在纯森陵于:1.不再使用with进行自动的上下文管理;2.使用while语句进行长连接的处理,如果需要能够自己控制长连接的关闭,那么可以设置一个变量比如conn_flag,初始化其值为True,当收到退出连接的命令时,将conn_flag置为False,即可实现连接春运的可控退出。
Enjoy it!

2. 如何使用WebSocket做接口测试

如果遇见了一个全新的协议,怎么从零开始,完成接口测试?以 WebSocket 为例。

WebSocket 协议在2008年诞生,2011年成为国际标准。现在所有浏览器都已经支持了。WebSocket 的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话。

WebSocket 的其他特点:

1. 建立在 TCP 协议之上,服务器端的实现比较容易。

2. 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器

3. 数据格式比较轻量,性能开销小,通信高效。

4. 可以发送文本,也可以发送二进制数据。

5. 没有同源限制,客户端可以与任意服务器通信。

6. 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。


· ws–>http(未加密) 无证书
· wss–>https(加密) 有证书


第一步:

很多时候第一反应向开发工程师求助,因为开发工程师基于新协议已经完成了接口开发,向开发工程师求助显然是最好的办法。找到一些学习脉络,包含了协议的说明文档、代码开发文档、实现代码等内容,了解协议的原理。向开发求助是个方法。

那么 WebSocket 用 Fiddler 怎么搞定?,其实主要就是修改了 Fiddler 中 Rules 下的 Customize Rules,如果感兴趣可以自己去搜一下。当面对陌生技术问题的时候,应该使用最熟悉的技术去尝试解决问题。虽然 Fiddler 截获 WebSocket 接口的办法,所截获的全部消息都在日志里面,根本无法操作。但是,可以借助 Fiddler 分析 WebSocket 的接口,一开始给 Fiddler 这款工具的定位一样,那就是通过它辅助分析我们的被测接口。处理HTTP、HTTPS,推荐用Fiddler。

但是在处理TCP,UDP 就用WireShark。Websocket是应用层协议,建立在 TCP 协议之上,服务器端的实现比较容易。因为应用层是在传输层的基础上包装数据,所以我们还是从底层开始了解Websocket到底是个啥?是如何工作的?


可以通过---- wireshark(网络封包分析软件)抓包工具抓到WebSocket接口

wireshark下载地址:https://www.wireshark.org/download.html

以下是python实现的websocket 接口连接。


3. 如何用python获取websocket数据

这里,介绍如何使用 Python 与前端 js 进行通信。
websocket 使用 HTTP 协议完成握手之后,不通过 HTTP 直接进行 websocket 通信。
于是,使用 websocket 大致两个步骤:使用 HTTP 握手,通信。
js 处理 websocket 要使用 ws 模块; python 处理则使用 socket 模块建立 TCP 连接即可,比一般的 socket ,只多一个握手以及数据处理的步骤。
握手
过程

包格式
js 客户端先向服务器端 python 发送握手包,格式如下:
?

1
2
3
4
5
6
7
8

GET
/chat HTTP/1.1
Host:
server.example.com
Upgrade:
websocket
Connection:
Upgrade
Sec-WebSocket-Key:
dGhlIHNhbXBsZSBub25jZQ==
Origin:
Sec-WebSocket-Protocol:
chat, superchat
Sec-WebSocket-Version:
13

服务器回应包格式:
?

1
2
3
4
5

HTTP/1.1
101 Switching Protocols
Upgrade:
websocket
Connection:
Upgrade
Sec-WebSocket-Accept:
s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol:
chat

其中, Sec-WebSocket-Key 是随机的,服务器用这些数据构造一个 SHA-1 信息摘要。
方法为: key+migic , SHA-1 加密, base-64 加密,如下:

Python 中的处理代码
?

1
2

MAGIC_STRING='258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
res_key=base64.b64encode(hashlib.sha1(sec_key
+MAGIC_STRING).digest())

握手完整代码
js 端
js 中有处理 websocket 的类,初始化后自动发送握手包,如下:
var socket = new WebSocket('ws://localhost:3368');
Python 端
Python 用 socket 接受得到握手字符串,处理后发送
?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

HOST='localhost'
PORT=3368
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"

defhandshake(con):
#con为用socket,accept()得到的socket

headers={}
shake=con.recv(1024)

ifnot

len(shake):
returnFalse

header,
data =shake.split('\r\n\r\n',1)
forline
inheader.split('\r\n')[1:]:
key,
val =line.split(':
',1)
headers[key]=val

if'Sec-WebSocket-Key'

not
in
headers:
print('This
socket is not websocket, client close.')
con.close()
returnFalse

sec_key=headers['Sec-WebSocket-Key']
res_key=base64.b64encode(hashlib.sha1(sec_key
+MAGIC_STRING).digest())

str_handshake=HANDSHAKE_STRING.replace('{1}',
res_key).replace('{2}',
HOST +':'

+
str(PORT))
printstr_handshake
con.send(str_handshake)
returnTrue

通信
不同版本的浏览器定义的数据帧格式不同, Python 发送和接收时都要处理得到符合格式的数据包,才能通信。
Python 接收
Python 接收到浏览器发来的数据,要解析后才能得到其中的有用数据。
浏览器包格式

固定字节:
( 1000 0001 或是 1000 0002 )这里没用,忽略
包长度字节:
第一位肯定是 1 ,忽略。剩下 7 个位可以得到一个整数 (0 ~ 127) ,其中
( 1-125 )表此字节为长度字节,大小即为长度;
(126)表接下来的两个字节才是长度;
(127)表接下来的八个字节才是长度;
用这种变长的方式表示数据长度,节省数据位。
mark 掩码:
mark 掩码为包长之后的 4 个字节,之后的兄弟数据要与 mark 掩码做运算才能得到真实的数据。
兄弟数据:
得到真实数据的方法:将兄弟数据的每一位 x ,和掩码的第 i%4 位做 xor 运算,其中 i 是 x 在兄弟数据中的索引。
完整代码
?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

defrecv_data(self,
num):
try:
all_data=self.con.recv(num)
ifnot

len(all_data):
returnFalse
except:
returnFalse
else:
code_len=ord(all_data[1])
& 127
ifcode_len
==126:
masks=all_data[4:8]
data=all_data[8:]
elifcode_len
==127:
masks=all_data[10:14]
data=all_data[14:]
else:
masks=all_data[2:6]
data=all_data[6:]
raw_str=""
i=0
ford
indata:
raw_str+=chr(ord(d)
^ ord(masks[i%4]))
i+=1
returnraw_str

js 端的 ws 对象,通过 ws.send(str) 即可发送
ws.send(str)
Python 发送
Python 要包数据发送,也需要处理,发送包格式如下

固定字节:固定的 1000 0001( ‘ \x81 ′ )
包长:根据发送数据长度是否超过 125 , 0xFFFF(65535) 来生成 1 个或 3 个或 9 个字节,来代表数据长度。
?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

defsend_data(self,
data):
ifdata:
data=str(data)
else:
returnFalse
token="\x81"
length=len(data)
iflength
< 126:
token+=struct.pack("B",
length)
eliflength
<=0xFFFF:
token+=struct.pack("!BH",126,
length)
else:
token+=struct.pack("!BQ",127,
length)
#struct为Python中处理二进制数的模块,二进制流为C,或网络流的形式。
data='%s%s'

%
(token, data)
self.con.send(data)
returnTrue

js 端通过回调函数 ws.onmessage() 接受数据
?

1
2
3
4
5

ws.onmessage
= function(result,nTime){
alert("从服务端收到的数据:");
alert("最近一次发送数据到现在接收一共使用时间:"+
nTime);
console.log(result);
}

最终代码
Python服务端
?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

#
_*_ coding:utf-8 _*_
__author__='Patrick'

importsocket
importthreading
importsys
importos
importMySQLdb
importbase64
importhashlib
importstruct

#
====== config ======
HOST='localhost'
PORT=3368
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"

classTh(threading.Thread):
def__init__(self,
connection,):
threading.Thread.__init__(self)
self.con=connection

defrun(self):
whileTrue:
try:
pass
self.con.close()

defrecv_data(self,
num):
try:
all_data=self.con.recv(num)
ifnot

len(all_data):
returnFalse
except:
returnFalse
else:
code_len=ord(all_data[1])
& 127
ifcode_len
==126:
masks=all_data[4:8]
data=all_data[8:]
elifcode_len
==127:
masks=all_data[10:14]
data=all_data[14:]
else:
masks=all_data[2:6]
data=all_data[6:]
raw_str=""
i=0
ford
indata:
raw_str+=chr(ord(d)
^ ord(masks[i%4]))
i+=1
returnraw_str

#
send data
defsend_data(self,
data):
ifdata:
data=str(data)
else:
returnFalse
token="\x81"
length=len(data)
iflength
< 126:
token+=struct.pack("B",
length)
eliflength
<=0xFFFF:
token+=struct.pack("!BH",126,
length)
else:
token+=struct.pack("!BQ",127,
length)
#struct为Python中处理二进制数的模块,二进制流为C,或网络流的形式。
data='%s%s'

%
(token, data)
self.con.send(data)
returnTrue

#
handshake
defhandshake(con):
headers={}
shake=con.recv(1024)

ifnot

len(shake):
returnFalse

header,
data =shake.split('\r\n\r\n',1)
forline
inheader.split('\r\n')[1:]:
key,
val =line.split(':
',1)
headers[key]=val

if'Sec-WebSocket-Key'

not
in
headers:
print('This
socket is not websocket, client close.')
con.close()
returnFalse

sec_key=headers['Sec-WebSocket-Key']
res_key=base64.b64encode(hashlib.sha1(sec_key
+MAGIC_STRING).digest())

str_handshake=HANDSHAKE_STRING.replace('{1}',
res_key).replace('{2}',
HOST +':'

+
str(PORT))
printstr_handshake
con.send(str_handshake)
returnTrue

defnew_service():
"""start
a service socket and listen
when
coms a connection, start a new thread to handle it"""

sock=socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
try:
sock.bind(('localhost',3368))
sock.listen(1000)
#链接队列大小
print"bind
3368,ready to use"
except:
print("Server
is already running,quit")
sys.exit()

whileTrue:
connection,
address =sock.accept()
#返回元组(socket,add),accept调用时会进入waite状态
print"Got
connection from ",
address
ifhandshake(connection):
print"handshake
success"
try:
t=Th(connection,
layout)
t.start()
print'new
thread for client ...'
except:
print'start
new thread error'
connection.close()

if__name__
=='__main__':
new_service()

js客户 端
?

1
2
3
4
5
6
7
8

<script>
varsocket
= newWebSocket('ws://localhost:3368');
ws.onmessage
= function(result,nTime){
alert("从服务端收到的数据:");
alert("最近一次发送数据到现在接收一共使用时间:"+
nTime);
console.log(result);
}
</script>

4. python怎么连接websocket

websocket是html5引入的一个新特性,传统的web应用是通过http协议来提供支持,如果要实时同步传输数据,需要轮询,效率低下

websocket是类似socket通信,web端连接服务器后,握手成功,一直保持连接,可以理解为长连接,这时服务器就可以主动给客户端发送数据,实现数据的自动更新。

使用websocket需要注意浏览器和当前的版本,不同的浏览器提供的支持不一样,因此设计服务器的时候,需要考虑。

阅读全文

与pythonwebsocket接口相关的资料

热点内容
程序员投行 浏览:313
java多线程读取文件 浏览:145
香港外贸服务器有什么好处 浏览:612
邓伦参加密室大逃脱结果变成团宠 浏览:847
购买文件服务器怎么选择 浏览:720
空调压缩机高压报警 浏览:498
u盘数控程序放哪个文件夹 浏览:853
python模拟微信登录其他APP 浏览:301
绑扎钢筋加密区规范 浏览:671
怎么更换手机壁纸安卓 浏览:808
闲鱼app卖手机怎么走验机 浏览:821
安卓三个按键音怎么关闭 浏览:64
esp8266手机app源码 浏览:713
服务器如何建立多个站点 浏览:151
加密狗可以在笔记本上做账吗 浏览:888
学生云服务器推荐 浏览:509
android银行卡快捷支付 浏览:828
海口手机直播系统源码 浏览:416
怎么给加密货币加图标 浏览:999
phpheader编码 浏览:766