在最近的项目(TestPaddlespeech)中,虽然在本地完成了一个语言识别算法,但是没有任何项目部署到服务器上,或者实现前后端交互的知识和技术。因此,通过一段时间的学习,找到了python中自带的一个websocket库,可以实现服务器的部署以及前后端的交互,因此记录自己的实现过程。
服务器,数据传输形式,前后端数据交互这些问题一直困扰着自己,该怎么实现这一过程,用什么技术路线,目前大致整理了一个方案出来,但是也都是东拼西凑的,应该没有多高的技术含量,也很想知道目前大厂的技术路线,如何实现这些功能。
在服务器端,采用的技术是websocket,代码为websocket_server2.py:
在客户端使用了一个websocket_client.py的文件,两者的连接是通过url的方式,eg:
ws://127.0.0.1:8181,就是这样一个ws开头的ip地址加端口号。
因为目前是部署在自己本地的电脑上的,所以有人告诉我说把ip地址换成自己的电脑ipv4的地址,至于为什么要这么做,自己就不得而知了。目前还没有搞明白。
这个是也是困扰自己很久的问题,该怎么传,是json,还是二进制比特流,还是base64加码之后的数据,没有确定。
所以最近尝试了使用base64加密和解密的方式,可以在服务器端还原文件了,先这样用着吧,以后要是改成别的方式,再说吧,在这里分享一个百度api接口的方式,个人还是很喜欢,觉得代码写的挺美的:
Python 技术篇-百度语音识别API接口调用演示_python语音识别到文本框中,怎么调接口-CSDN博客
import requests
import os
import base64
import json
apiUrl='http://vop.baidu.com/server_api'
filename = "16k.pcm" # 这是我下载到本地的音频样例文件名
size = os.path.getsize(filename) # 获取本地语音文件尺寸
file1 = open(filename, "rb").read() # 读取本地语音文件
text = base64.b64encode(file1).decode("utf-8") # 对读取的文件进行base64编码
data = {
"format":"pcm", # 音频格式
"rate":16000, # 采样率,固定值16000
"dev_pid":1536, # 普通话
"channel":1, # 频道,固定值1
"token":"24.0c828682d414bf79b08f89c4c7dcd83a.2592000.1562739150.282335-16470175", # 重要,鉴权认证Access Token,需要自己来申请
"cuid":"DC-85-DE-F9-08-59", # 随便一个值就好了,官网推荐是个人电脑的MAC地址
"len":size, # 语音文件的尺寸
"speech":text, # base64编码的语音文件
}
try:
r = requests.post(apiUrl, data = json.dumps(data)).json()
print(r)
print(r.get("result")[0])
except Exception as e:
print(e)
这个方式,先读取了数据,以二进制方式打开,然后通过base64加密,然后打包成json格式,写的真好啊。
自己的方式没有最后的json打包,过程如下:
client端代码:
#!/usr/bin/env python
import asyncio
import websockets
import json
import base64
async def test_ws_quote():
async with websockets.connect('ws://192.168.3.184:8181/quote/quote') as websocket:
req = {"protocol": "history_req", 'code': 'XAGODS', 'type': 'MINUTE', 'start_pos': '0', 'pos_num': '10'}
re = "12345678"
re = base64.b64encode(re.encode('utf-8'))
print(type(re))
file1 = open(r"E:\009901.wav", "rb").read() # 读取二进制文件
print(file1)
print("----------------------------------------------")
re = base64.b64encode(file1) # 进行编码
#尝试用来穿json格式
#await websocket.send(json.dumps(req))
#尝试用来传字符串格式
await websocket.send(re)
while True:
quote = await websocket.recv()
print(quote)
asyncio.get_event_loop().run_until_complete(test_ws_quote())
服务器端代码:接受到的数据为recv_text,重新写进一个文件中去,没有的话系统会重新创建,有的话系统会覆盖
#! -*- coding: utf-8 -*-
"""
Info: Websocket 的使用示例
10月28日,这份代码将作为自己连接的主力。可以实现和别的文件的连接。
python中,如何实现前端和后端的数据交互,这是使用过websocket来写的,包括了建立连接
,接受数据和返回数据等相关的功能。
"""
import asyncio
import websockets
import base64
websocket_users = set()
# 检测客户端权限,用户名密码通过才能退出循环
async def check_user_permit(websocket):
print("new websocket_users:", websocket)
websocket_users.add(websocket)
print("websocket_users list:", websocket_users)
while True:
recv_str = await websocket.recv()
cred_dict = recv_str.split(":")
if cred_dict[0] == "admin" and cred_dict[1] == "123456":
response_str = "Congratulation, you have connect with server..."
await websocket.send(response_str)
print("Password is ok...")
return True
else:
response_str = "Sorry, please input the username or password..."
print("Password is wrong...")
await websocket.send(response_str)
# 接收客户端消息并处理,这里只是简单把客户端发来的返回回去
async def recv_user_msg(websocket):
#把新连接的用户显示出来:
print("new websocket_users:", websocket)
websocket_users.add(websocket)
print("websocket_users list:", websocket_users)
while True:
recv_text = await websocket.recv()
print("recv_text:", websocket.pong, recv_text)
response_text = f"Server return: {recv_text}"
print(type(recv_text))
#加上下面两行试一下解码
#经过测试如果是音频二进制文件,通过base64.b64encode(file1)编码之后传送,再通过base64.b64decode(recv_text)解码,可以得到原来的二进制文件
re = base64.b64decode(recv_text)
print(re)
print(type(re))
#下面来测试怎么把收到的二进制音频流转化为音频保存。
file2 = open(r"E:\websocket_output.wav","wb")
file2.write(re)
#在此页面显示要重新发回的数据(内容)
print("response_text:", response_text)
#这就话是将收到的数据原封不动的发回去。
await websocket.send(response_text)
# 服务器端主逻辑
async def run(websocket, path):
while True:
try:
#await check_user_permit(websocket)
await recv_user_msg(websocket)
except websockets.ConnectionClosed:
print("ConnectionClosed...", path) # 链接断开
print("websocket_users old:", websocket_users)
websocket_users.remove(websocket)
print("websocket_users new:", websocket_users)
break
except websockets.InvalidState:
print("InvalidState...") # 无效状态
break
except Exception as e:
print("Exception:", e)
if __name__ == '__main__':
print("127.0.0.1:8181 websocket...")
asyncio.get_event_loop().run_until_complete(websockets.serve(run, "192.168.3.184", 8181))
asyncio.get_event_loop().run_forever()
借鉴的CSDN博客:
服务器端:
【Python】Python3 使用 Websocket 示例_websocket例子python-CSDN博客
客户端:
python一个简单的websocket测试客户端-CSDN博客