Read the content of the uploaded file and follow t...
创建于:2025年7月13日
创建于:2025年7月13日
Below is a concrete implementation roadmap that reconstructs the SIP Server so it can speak “SIP over WebSocket” and fulfils every item in the file’s TASK list. Citations point back to the exact lines in your markdown where each requirement originated.
Layer | New / changed component | Purpose | Key APIs / libs |
---|---|---|---|
WebSocket transport | SipWebSocketServer (dedicated, runs in its own thread) | Terminates WS/WSS hand-shakes, frames/unframes SIP messages, enforces connection limits/timeouts from [sip_websocket] section. | uWebSockets (already deps) |
Transport bridge | WsSipTransport (new C++20 class) | Converts raw SIP text ↔ osip_message_t* , injects into eXosip2 with eXosip_message_receive / eXosip_message_send_* wrappers. Maintains bidirectional map <uWS::WebSocket*, eXosip tid/cid> for routing responses. | eXosip2 |
Core SIP server | SipProxy , SipLocation , extended ContactBinding | Now stores transportType enum {UDP,TCP,TLS,WS,WSS} so routing is transport-aware. | existing |
Simulated callers | SipSimulatedClient , SipSimulatedClientManager | Add WebSocket support by delegating to WsSipTransport when peer’s transportType==WS/WSS . | existing + new bridge |
Config | [sip_websocket] section already present | Enables/parametrises the WS listener (host/port, TLS certs, limits, auth) | inih |
Why a dedicated SipWebSocketServer instead of embedding a handler in the monolithic
SipServer
?
- Loose-coupling keeps SIP over WS concerns (hand-shake, ping/pong, per-socket state) out of SIP transaction logic.
- You already run REST and HTTP in separate classes (
HttpServer
,WebsocketServer
) so this is consistent.- Allows optional compile-time inclusion via
ENABLE_SIP_WS
flag without touching core threads.
REGISTER
text frameSipWebSocketServer
receives frame → hands raw string to WsSipTransport::onRx()
WsSipTransport
parses text into osip_message_t*
via osip_message_parse()
and injects into eXosip2 with eXosip_message_receive()
SipLocation
adds/updates ContactBinding{…, transportType=WS, wsPath=<socket-ptr>}WsSipTransport::onTx()
which serialises and sends back as a WebSocket text frame.SipSimulatedClient
or another UA can now route INVITE to this AOR; SipProxy
picks WS transport via the extended binding.cpp// ContactBinding.hpp enum class TransportType { UDP, TCP, TLS, WS, WSS }; struct ContactBinding { std::string contactUri; std::chrono::steady_clock::time_point expiry; TransportType transport; // NEW void* wsHandle = nullptr; // NEW – for fast look-up };
cpp// WsSipTransport.hpp (simplified) class WsSipTransport { public: void registerSocket(uWS::WebSocket<false,true,PerSocketData>* ws); void onRx(uWS::WebSocket<false,true,PerSocketData>* ws, std::string_view msg); void onTx(uWS::WebSocket<false,true,PerSocketData>* ws, osip_message_t* sip); private: eXosip_t* m_ctx; std::unordered_map<uWS::WebSocket<false,true,PerSocketData>*, std::string /*call-id*/> m_map; };
cpp// SipProxy routing excerpt auto bindings = SipLocation::ins().getBindings(targetAor); for (auto& b : bindings) { switch (b.transport) { case TransportType::WS: case TransportType::WSS: WsSipTransport::ins().send(invite, b.wsHandle); break; default: sendViaUdpTcp(invite, b); } }
ENABLE_SIP_WS
option and link uWebSockets only if enabled.
cmakeif(ENABLE_SIP_WS) find_package(uWebSockets REQUIRED) target_sources(ghtsip PUBLIC src/sipws/SipWebSocketServer.cpp src/sipws/WsSipTransport.cpp) target_link_libraries(ghtsip uWS::uWS) endif()
[sip_websocket]
block you already drafted (listen_addr/port, TLS, limits) is parsed in ServerConfig::parseConfig
lines 42-52.SipWebSocketServer
behind if(conf.sipWsEnable)
before starting the SIP core; shutdown order mirrors existing HTTP/REST sequence.ENABLE_SIP_WS
) and compile with empty stub classes to keep master green.SipWebSocketServer
accepting WS hand-shakes, echo ping-pong, log raw frames for debugging.WsSipTransport
to parse/serialise SIP, inject into eXosip2; verify REGISTER/200 OK round-trip with SIP.js.SipProxy
/SipSimulatedClient
for transport-aware routing; test browser⇄browser and SimulatedClient→browser INVITE flows.require_auth=true
.WebsocketServer
if redundant.WsSipTransport
(§1, §3) directly addresses bullet 2.SipWebSocketServer
fulfils bullet 5 and explains rationale.[sip_websocket]
already captured and parsed (§4), bullet 6.Feel free to ask for deeper dives (e.g., full bridging code, eXosip callback wiring, or SDP tweaks) and I can expand on those parts.