要实时订阅RESTful服务端资源ac_status的状态,你需要使用WebSocket或者Server-Sent Events(SSE)。这两种技术都可以让服务器向客户端推送更新。
使用WebSocket协议:使服务端向客户端发送通知,客户端可实时接收空调状态(模拟空调)
使用RESTful 架构http协议:使客户端向服务端发送POST请求,更改空调状态(模拟相关控制空调的车载APP)
一、以下是使用WebSocket的示例:
服务端代码如下:
import asyncio
import json
import threading
import websockets
from flask import Flask, request
app = Flask(__name__)
# 假设空调的初始状态 8000 change status and 50000 notify status
ac_status = {
'on': True,
'temperature': 22
}
clients = set()
@app.route('/ac/status', methods=['GET'])
def get_ac_status():
return ac_status
@app.route('/ac/on', methods=['POST'])
def turn_on_ac():
print("---------turn_on_ac-----")
# ac_status['on'] = True
if ac_status['on']:
print("air already open")
else:
print("False---->True")
ac_status['on'] = True
# notify_clients()
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(notify_clients())
loop.close()
return ac_status
@app.route('/ac/off', methods=['POST'])
def turn_off_ac():
print("---------turn_off_ac-----")
ac_status['on'] = False
# notify_clients()
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(notify_clients())
loop.close()
print("turn off ac_status====",ac_status)
return ac_status
@app.route('/ac/setTemperature', methods=['POST'])
def set_ac_temperature():
temperature = request.args.get('temp')
if temperature:
ac_status['temperature'] = int(temperature)
# notify_clients()
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(notify_clients())
loop.close()
return ac_status
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:
await websocket.recv()
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()
def run_flask_app():
app.run(host='0.0.0.0', port=8000)
# start_server = websockets.serve(server, "localhost", 5000)
start_server = websockets.serve(server, "0.0.0.0", 5000)
if __name__ == '__main__':
asyncio.get_event_loop().run_until_complete(start_server)
#开启 此处服务端会每隔3s自动更改空调状态
# asyncio.ensure_future(auto_change_ac_status())
flask_thread = threading.Thread(target=run_flask_app)
flask_thread.start()
asyncio.get_event_loop().run_forever()
在这个示例中,我们创建了一个WebSocket服务器,它监听localhost:5000。当有新的客户端连接时,我们将它添加到clients集合中。当有客户端断开连接时,我们将它从clients集合中移除。
我们还添加了一个notify_clients函数,当空调状态改变时,它会通知所有连接的客户端。
注意,这个示例使用了asyncio库,这是Python 3.4引入的一个异步IO库。如果你使用的是Python 2.x,你可能需要使用其他的异步IO库,比如Twisted。
另外,如果你的服务器只绑定到 localhost(即只监听 127.0.0.1),那么它将只能从同一台机器上访问。如果你想要从其他机器访问,你需要将服务器绑定到所有可用的网络接口,例如 0.0.0.0。
客户端一(模拟空调控制器):
要实现实时通知,你需要在客户端和服务端都使用WebSocket。服务端已经使用了WebSocket,而客户端可以使用C++的websocket库,如cpprestsdk
。
#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;
int main()
{
websocket_callback_client client;
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;
});
// 阻塞主线程,防止退出
std::string line;
std::getline(std::cin, line);
return 0;
}
这个客户端连接到服务端的WebSocket服务,并设置一个消息处理函数,该函数在接收到消息时被调用。消息被解析为JSON,然后提取出状态和温度,并打印出来。
请注意,这个客户端会一直运行,直到你手动停止它。如果你希望它在接收到消息后自动关闭,你需要在消息处理函数中添加一些逻辑来关闭WebSocket连接。
客户端二(模拟车载APP):
(1)以下是使用cpprest库的C++示例:
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <cpprest/json.h>
using namespace utility;
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace concurrency::streams;
int main()
{
http_client client(U("http://192.168.48.129:8000/"));
// 打开空调
http_request request(methods::POST);
request.set_request_uri(U("ac/on"));
client.request(request).get();
// 关闭空调
request = http_request(methods::POST);
request.set_request_uri(U("ac/off"));
client.request(request).get();
// 设置空调温度
request = http_request(methods::POST);
request.set_request_uri(U("ac/setTemperature?temp=25"));
client.request(request).get();
return 0;
}
(2)使用Python的requests
库来发送HTTP POST请求。以下是如何使用requests
库来发送POST请求的示例:
import requests
# 关闭空调
print("--------关闭空调-------")
response = requests.post('http://192.168.48.129:8000/ac/off')
print(response.text)
#服务器返回的是JSON,使用如下
# 关闭空调
# print("--------关闭空调-------")
# response = requests.post('http://localhost:5000/ac/off')
# print(response.json())
# # 打开空调
# print("--------打开空调-------")
# response = requests.post('http://localhost:5000/ac/on')
# print(response.json())
# # 设置空调温度
# print("--------设置空调温度-------")
# response = requests.post('http://localhost:5000/ac/setTemperature', params={'temp': 25})
# print(response.json())
二、代码所需软件包的安装:
服务端依赖
1、安装websockets库
pip install websockets 或
sudo apt-get install libwebsocketpp-dev
2、安装flask
pip install flask 或
pip install flask -i https://pypi.python.org/simple
//上面安装还是不成功 可以升级pip后重试
pip install --upgrade pip
3、安装Python3
(1)在Linux上,你可以通过包管理器来安装Python 3。例如,在Ubuntu上,你可以通过以下命令来安装Python 3:
sudo apt-get update
sudo apt-get install python3
(2)让python
命令默认指向Python 3,你可以创建一个符号链接。首先,你需要找到Python 3的路径,可以通过which python3
命令来找到。然后,你可以使用sudo ln -s /path/to/python3 /usr/bin/python
命令来创建一个符号链接。
注意:在执行ln -s
命令时,你需要替换/path/to/python3
为实际的Python 3路径。
例如,如果你的Python 3路径是/usr/bin/python3
,你可以使用以下命令:
sudo ln -s /usr/bin/python3 /usr/bin/python
然后检查Python版本,它应该显示Python 3的版本。你可以使用以下命令:
python --version
注:如果/usr/bin/python
已经存在,并且是一个文件,而不是一个符号链接。这通常是因为你的系统已经安装了Python 2。
-
首先,你需要确定Python 2的路径。你可以通过
which python
命令来找到。 -
然后,你可以使用
sudo mv
命令来将Python 2的路径重命名。例如,如果你的Python 2路径是/usr/bin/python
,你可以使用以下命令:sudo mv /usr/bin/python /usr/bin/python2
-
最后,你可以使用
sudo ln -s
命令来创建一个指向Python 3的符号链接。例如,如果你的Python 3路径是/usr/bin/python3
,你可以使用以下命令:sudo ln -s /usr/bin/python3 /usr/bin/python
这样,你就可以通过
python
命令来运行Python 3了。
客户端一依赖
1、安装cpprestsdk库
(1)cpprestsdk
库是一个跨平台的C++ REST库,它可以用于构建基于REST的服务和客户端。以下是安装cpprestsdk
的步骤:
方法一:在Ubuntu或Debian上,你可以使用以下命令安装cpprestsdk
:
sudo apt-get install libcpprest-dev
方法二:通过源代码编译
-
从GitHub克隆
cpprestsdk
的源代码:git clone https://github.com/Microsoft/cpprestsdk.git
-
进入
cpprestsdk
的目录,并创建一个构建目录:cd cpprestsdk mkdir build cd build
-
使用CMake生成构建文件:
cmake ..
-
编译和安装
cpprestsdk
:make sudo make install
(2)查看是否安装cpprestsdk库
在Linux上,你可以使用pkg-config
工具来查看是否安装了cpprestsdk
。在终端中输入以下命令:
pkg-config --modversion libcpprest
如果cpprestsdk
已经安装,那么这个命令将返回cpprestsdk
的版本号。如果没有安装,那么这个命令将返回一个错误。
2、安装 Boost, OpenSSL, ZLib 和 CppUnit
(1)安装:
sudo apt-get update
sudo apt-get install libboost-all-dev libssl-dev libz-dev cppunit
(2)使用:
如果你在使用 CMake 来构建你的项目,你可以在你的 CMakeLists.txt
文件中添加以下代码:
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "path/to/cpprestsdk/share/cmake")
find_package(cpprestsdk REQUIRED)
add_executable(your_project your_project.cpp)
target_link_libraries(your_project PRIVATE cpprest)
如下所示添加到CMakeLists.txt
文件中:
客户端二依赖:
安装requests
库。你可以使用以下命令来安装:
pip install requests
三、结果展示
四、代码相关知识
1、服务端
服务端包括 WebSocket服务器和Flask应用两个服务。Flask应用需要在一个HTTP服务器上运行,而WebSocket服务器则不需要。
(1)WebSocket协议的使用参考链接:我们来谈谈websocket_websocket 线程_RNGWGzZs的博客-CSDN博客文章浏览阅读998次。一、初始WebSocket"你一无所有地闯荡。一、初始WebSocket(1) 什么是websocket是一种在单个TCP连接上进行全双工通信的协议。使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。websocket是从HTML5开始⽀持的⼀种⽹⻚端和服务端保持"⻓连接"的消息推送机制。_websocket 线程https://blog.csdn.net/RNGWGzZs/article/details/131303941文章来源:https://www.toymoban.com/news/detail-770975.html
(2)async def函数
在Python中,如果一个函数被定义为协程(使用async def
定义),那么在调用它时必须使用await
关键字。文章来源地址https://www.toymoban.com/news/detail-770975.html
到了这里,关于使用websockets和RESTful通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!