代码如下,因为是初次尝试,所以比较简单。我自己用python写的服务端,使用python是可以连接的。会输出下面这行东西:
_PROCESS_REQUEST: Request(path='/', headers=Headers([('Host', 'localhost:8765'), ('Upgrade', 'websocket'), ('Connection', 'Upgrade'), ('Sec-WebSocket-Key', '0itrtPOKGWQ1euqU2wwd6Q=='), ('Sec-WebSocket-Version', '13'), ('Sec-WebSocket-Extensions', 'permessage-deflate; client_max_window_bits'), ('User-Agent', 'Python/3.11 websockets/14.1')]), exception=None)
Received: {"method": "SUBSCRIBE", "params": [], "id": 1}
但是如果使用下面的C++代码就会直接退出,除了下面这行没有其余如何输出
Debug\ws_0.exe (进程 36732)已退出,代码为 0 (0x0)。
请各大伙帮我看一下问题在哪里,谢谢!
#define _CRT_SECURE_NO_WARNINGS // 禁用不安全警告
#include <iostream>
#include "uwebsockets/App.h"
int main() {
/* ws->getUserData returns one of these */
struct PerSocketData {
uWS::CompressOptions compression = uWS::DISABLED;
unsigned int maxPayloadLength = 16 * 1024;
unsigned short idleTimeout = 120;
unsigned int maxBackpressure = 64 * 1024;
bool closeOnBackpressureLimit = false;
bool resetIdleTimeoutOnSend = false;
bool sendPingsAutomatically = true;
unsigned short maxLifetime = 0;
};
uWS::App().ws<PerSocketData>("/*", {
.upgrade = [&](auto* res, auto* req, auto* context) {
// 从请求中提取必要的 WebSocket 握手头部字段
std::string_view url = req->getUrl();
std::string_view secWebSocketKey = req->getHeader("sec-websocket-key");
std::string_view secWebSocketProtocol = req->getHeader("sec-websocket-protocol");
std::string_view secWebSocketExtensions = req->getHeader("sec-websocket-extensions");
std::cout << "Upgrade requested for URL: " << url << std::endl;
std::cout << "sec-websocket-key: " << secWebSocketKey << std::endl;
std::cout << "sec-websocket-protocol: " << secWebSocketProtocol << std::endl;
std::cout << "sec-websocket-extensions: " << secWebSocketExtensions << std::endl;
// 你可以在这里进行一些校验,例如检查 origin 或 token
// 如果需要拒绝升级,可以调用 res->end("拒绝升级");
// 调用 upgrade() 完成升级,并为该连接分配一个新的 PerSocketData 对象
res->upgrade(
new PerSocketData(), // 指向用户数据的指针,连接关闭时会被释放
secWebSocketKey, // WebSocket 握手关键头部
secWebSocketProtocol, // 协议
secWebSocketExtensions, // 扩展
context // HTTP 上下文(内部使用,不用更改)
);
},
.open = [](auto* ws) {
std::cout << "WebSocket connected!" << std::endl;
// 发送一条测试消息
ws->send("Hello, server!");
},
.message = [](auto* ws, std::string_view message, uWS::OpCode opCode) {
std::cout << "Received message from server: " << message << std::endl;
},
.close = [](auto* ws, int code, std::string_view message) {
std::cout << "Connection closed with code " << code << " and message: " << message << std::endl;
}
}).connect("ws://localhost:8765", nullptr) // 假设的 WebSocket 地址
.run();
return 0;
}
python 服务端的代码
import asyncio
import websockets
from datetime import datetime
# Set of connected clients
connected_clients = set()
async def handler(websocket):
# Add the client to the connected clients set
connected_clients.add(websocket)
try:
# Keep listening for incoming messages from the client
async for message in websocket:
# Broadcast the message to all connected clients
print('Received: ', message)
await broadcast(message)
except Exception as e:
print('handler出现错误: %s' % e)
finally:
connected_clients.remove(websocket)
async def process_request(connection, req):
print('PROCESS_REQUEST:', req)
async def process_response(connection, req, res):
print('PROCESS_RESPONSE:', req, res)
async def broadcast(message):
# Broadcast the message to all connected clients
try:
for client in connected_clients:
await client.send(message)
except Exception as e:
print('broadcast出现错误: %s' % e)
async def main():
async with websockets.serve(handler, "localhost", 8765,
process_request=process_request,
process_response=None):
await asyncio.Future() # run forever
loop = asyncio.get_running_loop() #获取当前event_loop对象
loop.create_task(broadcast()) # 添加新的异步广播任务
if __name__ == "__main__":
asyncio.run(main())