使用websockets通信

 一、HTTP WebSocket

   先来看一下HTTP WebSocket的关系,以及为什么使用websockets不使用HTTP

(1)关系: 

  1. HTTP (Hypertext Transfer Protocol): HTTP 是万维网的数据通信的核心。它是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP 是无状态的,意味着每个请求都是独立的,服务器不会在两个请求之间保留任何数据(状态)。

  2. RESTful: RESTful 是一种基于 HTTP 的架构风格,它定义了一组约束条件和原则,用于创建 Web 服务。这些约束条件和原则包括使用 HTTP 方法(如 GET、POST、PUT、DELETE),使用 URI 来标识资源,以及使用 HTTP 状态码来表示请求的结果。

  3. WebSocket: WebSocket 是一种在单个 TCP 连接上提供全双工通信信道的协议。它提供了一种在客户端和服务器之间进行双向通信的机制。WebSocket 协议在 HTTP 协议的基础上进行了扩展,以实现全双工通信。

这三种协议的关系可以这样理解:HTTP 是基础,RESTful 是基于 HTTP 的一种设计风格,而 WebSocket 是 HTTP 协议的扩展,用于实现实时双向通信。

(2)为什么使用websockets不使用HTTP:

  • 使用http

        原生的http能实现吗? 当然!客户端显然可以采用一种 "轮询"的⽅式,不停向服务器发送http报头,得到结果反馈。但这其实是一种 "伪服务器推"的方式,并且 轮询的成本⽐较⾼,服务端也不能及时的获取到消息的响应。

  • 使用WebSocket

        使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输,适用于服务器和客户端需要大量数据交互的场景。

大家可以看一下此链接,将HTTP 和WebSocket的关系讲的很通俗易懂,参考链接我们来谈谈websocket_websocket 线程_RNGWGzZs的博客-优快云博客

二、代码示例

服务端:接收客户端的消息--->更改空调状态(全局变量ac_status['on'])--->发送通知给所有客户端(空调状态改变)
客户端:发送消息给服务端,更改服务端空调的状态 + 实时接收服务端发送的通知(空调状态)

注:打开这个auto_change_ac_status函数,服务端每3秒可自动更改一次空调状态

服务端(Python):

import asyncio
import json
import websockets

ac_status = {
    'on': True,
    'temperature': 22
}

clients = set()

async def notify_clients():
    print("--------notify_clients-------")
    if clients:
        message = json.dumps(ac_status)
        await asyncio.wait([client.send(message) for client in clients])
    print(ac_status)

async def server(websocket, path):
    print("server")
    clients.add(websocket)
    if clients:
         print("clients exit")
         await notify_clients()
    else :
         print("clients no exit !!!")
    try:
        received_message=await websocket.recv()
        print(f"Received message: {received_message}")
         # 根据接收到的消息更改空调的状态
        if received_message == "turn on":
            ac_status['on'] = True
            await notify_clients()
        elif received_message == "turn off":
            ac_status['on'] = False
            await notify_clients()
        elif received_message.startswith("set temperature"):
            temperature = int(received_message.split()[-1])
            ac_status['temperature'] = temperature
            await notify_clients()
    finally:
        clients.remove(websocket)

async def auto_change_ac_status():
    print("auto_change_ac_status")
    while True:
        print("sleep")
        await asyncio.sleep(3)  # 等待10秒
        if ac_status['on']:
            print("True---->False")
            ac_status['on'] = False
            await notify_clients()
        else:
            print("False---->True")
            ac_status['on'] = True
            await notify_clients()

start_server = websockets.serve(server, "0.0.0.0", 5000)

if __name__ == '__main__':
  
    asyncio.get_event_loop().run_until_complete(start_server)
    # asyncio.ensure_future(auto_change_ac_status())
    asyncio.get_event_loop().run_forever()

客户端(C++):


#include <cpprest/ws_client.h>
#include <cpprest/json.h>
using namespace std;
using namespace utility;
using namespace web;
using namespace web::websockets::client;
using namespace concurrency::streams;

websocket_callback_client client;

void send_message(string message) {
    websocket_outgoing_message msg;
    msg.set_utf8_message(message);
    client.send(msg).wait();
}

int main()
{
    client.connect(U("ws://192.168.48.129:5000/")).wait();
    client.set_message_handler([&](websocket_incoming_message msg) {
        auto response = msg.extract_string().get();
        auto jsonResponse = web::json::value::parse(response);
        auto status = jsonResponse[U("on")].as_bool();
        auto temperature = jsonResponse[U("temperature")].as_integer();
        std::cout << "Received status: " << status << ", temperature: " << temperature << std::endl;
    });

    send_message("turn off");
    
    //阻塞主线程  防止退出
    std::string line;
    std::getline(std::cin, line);

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值