使用websocket客户机和服务器实现通讯

前言

在最近的项目(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博客

你可能感兴趣的:(websocket,服务器,网络协议,python)