websocket python3实现_Python3+WebSockets实现WebSocket通信

一、说明

1.1 背景说明

前段时间同事说云平台通信使用了个websocket的东西,今天抽空来看一下具体是怎么个通信过程。

从形式上看,websocket是一个应用层协议,socket是数据链路层、网络层、传输层的抽像;从应用场合上看,websocket可以使用javascript实现,而socket不能用javascript实现(真不能吗?我不太确定);从实际效果上看,和一般的socket连接用起来没什么区别。

我们知道http是短连接的,反复建立和销毁连接比较耗费资源,另外http协议经常头部内容比主体内容还长也比较浪费资源;websocket可以认为就是一个内容使用载荷固定格式的socket长连接。

websocket基本协议格式如下,更多说明见RFC 6455:

1.2 环境说明

当前环境我使用Python3+WebSockets库,WebSockets直接使用pip安装即可:

pip install websockets

二、代码实现

长连接是有状态的,所以一般在且只在最开始进行一次身份认证,而后通信过程不需要认证信息。我们这里实现一个简单的用户名密码认证过程。长连接更多内容可参考“长连接与短连接的安全差异讨论”。

另外,注意把代码中的ip改成自己的。

2.1 python服务端代码

importasyncioimportwebsockets#检测客户端权限,用户名密码通过才能退出循环

async defcheck_permit(websocket):whileTrue:

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\r\nnow, you can do something else"await websocket.send(response_str)returnTrueelse:

response_str= "sorry, the username or password is wrong, please submit again"await websocket.send(response_str)#接收客户端消息并处理,这里只是简单把客户端发来的返回回去

async defrecv_msg(websocket):whileTrue:

recv_text=await websocket.recv()

response_text= f"your submit context: {recv_text}"await websocket.send(response_text)#服务器端主逻辑#websocket和path是该函数被回调时自动传过来的,不需要自己传

async defmain_logic(websocket, path):

await check_permit(websocket)

await recv_msg(websocket)#把ip换成自己本地的ip

start_server = websockets.serve(main_logic, '10.10.6.91', 5678)#如果要给被回调的main_logic传递自定义参数,可使用以下形式#一、修改回调形式#import functools#start_server = websockets.serve(functools.partial(main_logic, other_param="test_value"), '10.10.6.91', 5678)#修改被回调函数定义,增加相应参数#async def main_logic(websocket, path, other_param)

asyncio.get_event_loop().run_until_complete(start_server)

asyncio.get_event_loop().run_forever()

2.2 python版客户端代码

importasyncioimportwebsockets#向服务器端认证,用户名密码通过才能退出循环

async defauth_system(websocket):whileTrue:

cred_text= input("please enter your username and password:")

await websocket.send(cred_text)

response_str=await websocket.recv()if "congratulation" inresponse_str:returnTrue#向服务器端发送认证后的消息

async defsend_msg(websocket):whileTrue:

_text= input("please enter your context:")if _text == "exit":print(f'you have enter "exit", goodbye')

await websocket.close(reason="user exit")returnFalse

await websocket.send(_text)

recv_text=await websocket.recv()print(f"{recv_text}")#客户端主逻辑

async defmain_logic():

async with websockets.connect('ws://10.10.6.91:5678') as websocket:

await auth_system(websocket)

await send_msg(websocket)

asyncio.get_event_loop().run_until_complete(main_logic())

2.3 html版客户端代码

html版客户端代码,只能通过回调函数接收服务端返回的数据,不能主动接收,感觉怪怪的。

websocket通信客户端

functionWebSocketTest()

{if("WebSocket" inwindow)

{//打开一个 web socket

varws= newWebSocket("ws://10.10.6.91:5678");//连接建立后的回调函数

ws.onopen= function()

{//Web Socket 已连接上,使用 send() 方法发送数据

ws.send("admin:123456");

alert("正在发送:admin:123456");

};//接收到服务器消息后的回调函数

ws.onmessage= function(evt)

{varreceived_msg=evt.data;if(received_msg.indexOf("sorry")== -1) {

alert("收到消息:"+received_msg);

}

};//连接关闭后的回调函数

ws.onclose= function()

{//关闭 websocket

alert("连接已关闭...");

};

}else{//浏览器不支持 WebSocket

alert("您的浏览器不支持 WebSocket!");

}

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值