Rabbit Remote Control 0.0.30
Loading...
Searching...
No Matches
IceSignalWebSocket.cpp
1
2
3#include "IceSignalWebSocket.h"
4
5#include <nlohmann/json.hpp>
6
7#include <QDebug>
8
10{
11 m_webSocket = std::make_shared<rtc::WebSocket>();
12}
13
14CIceSignalWebSocket::~CIceSignalWebSocket()
15{
16 qDebug() << "CIceSignalWebSocket::~CIceSignalWebSocket()";
17}
18
19int CIceSignalWebSocket::Write(const char *buf, int nLen)
20{
21 bool bRet = 0;
22 QMutexLocker lock(&m_MutexSend);
23 if(m_webSocket)
24 {
25 bRet = m_webSocket->send(std::string(buf, nLen));
26 if(bRet)
27 return nLen;
28 }
29 return -1;
30}
31
32int CIceSignalWebSocket::Read(char *buf, int nLen)
33{
34 int n = nLen;
35 Q_ASSERT(false);
36 return n;
37}
38
39int CIceSignalWebSocket::Open(const std::string &szServer, quint16 nPort,
40 const std::string &user, const std::string &password)
41{
42 Q_UNUSED(password);
43 std::string szUrl;
44 std::string wsPrefix = "ws://";
45
46 const std::string url = wsPrefix + szServer + ":" +
47 std::to_string(nPort) + "/" + user;
48 qDebug(m_Log, "Url is %s", url.c_str());
49 return Open(url, user, password);
50}
51
52int CIceSignalWebSocket::Open(const std::string &szUrl,
53 const std::string &user,
54 const std::string &password)
55{
56 Q_UNUSED(password);
57 if(!m_webSocket)
58 m_webSocket = std::make_shared<rtc::WebSocket>();
59 if(!m_webSocket) return -1;
60
61 m_webSocket->onOpen([this]() {
62 qDebug(m_Log, "WebSocket is open");
63 emit sigConnected();
64 });
65 m_webSocket->onError([this](std::string szErr) {
66 qDebug(m_Log, "WebSocket is error");
67 emit sigError(-1, szErr.c_str());
68 });
69 m_webSocket->onClosed([this]() {
70 qDebug(m_Log, "WebSocket is close");
71 emit sigDisconnected();
72 });
73 m_webSocket->onMessage([this](std::variant<rtc::binary, std::string> data) {
74 if (!std::holds_alternative<std::string>(data))
75 return;
76
77 nlohmann::json message = nlohmann::json::parse(std::get<std::string>(data));
78
79 auto it = message.find("id");
80 if (it == message.end())
81 return;
82 it = message.find("toUser");
83 if (it == message.end())
84 return;
85 std::string toUser = it->get<std::string>();
86 it = message.find("fromUser");
87 if (it == message.end())
88 return;
89 std::string fromUser = it->get<std::string>();
90 it = message.find("channelid");
91 if (it == message.end())
92 return;
93 std::string channelid = it->get<std::string>();
94
95 it = message.find("type");
96 if (it == message.end())
97 return;
98 std::string type = it->get<std::string>();
99
100 if(type == "offer")
101 {
102 auto sdp = message["description"].get<std::string>();
103 emit sigOffer(fromUser.c_str(), toUser.c_str(), channelid.c_str(),
104 type.c_str(), sdp.c_str());
105 }
106 else if(type == "answer") {
107 auto sdp = message["description"].get<std::string>();
108 emit sigDescription(fromUser.c_str(), toUser.c_str(),
109 channelid.c_str(), type.c_str(), sdp.c_str());
110 } else if (type == "candidate") {
111 auto sdp = message["candidate"].get<std::string>();
112 auto mid = message["mid"].get<std::string>();
113 emit sigCandiate(fromUser.c_str(), toUser.c_str(),
114 channelid.c_str(), mid.c_str(), sdp.c_str());
115 }
116 });
117
118 m_szUser = user;
119 m_szUrl = szUrl;
120 try {
121 m_webSocket->open(szUrl);
122 } catch (std::exception &e) {
123 qCritical(m_Log,
124 "Open websocket fail: %s; %s",
125 e.what(), szUrl.c_str());
126 return -1;
127 }
128
129 return 0;
130}
131
132int CIceSignalWebSocket::Close()
133{
134 if(!m_webSocket) return -1;
135 m_webSocket->close();
136 return 0;
137}
138
139bool CIceSignalWebSocket::IsOpen()
140{
141 if(m_webSocket)
142 return m_webSocket->isOpen();
143 return false;
144}
145
146int CIceSignalWebSocket::SendCandiate(const QString& toUser,
147 const QString &channelId,
148 const rtc::Candidate &candidate,
149 const QString &fromUser)
150{
151 std::string user = fromUser.toStdString();
152 if(user.empty())
153 user = m_szUser;
154 nlohmann::json message = {{"id", toUser.toStdString()},
155 {"toUser", toUser.toStdString()},
156 {"fromUser", user},
157 {"channelid", channelId.toStdString()},
158 {"type", "candidate"},
159 {"candidate", std::string(candidate)},
160 {"mid", candidate.mid()}};
161
162 std::string m = message.dump();
163 return Write(m.c_str(), m.size());
164}
165
166int CIceSignalWebSocket::SendDescription(const QString& toUser,
167 const QString& channelId,
168 const rtc::Description &description,
169 const QString& fromUser)
170{
171 std::string user = fromUser.toStdString();
172 if(user.empty())
173 user = m_szUser;
174 nlohmann::json message = {
175 {"id", toUser.toStdString()},
176 {"toUser", toUser.toStdString()},
177 {"fromUser", user},
178 {"channelid", channelId.toStdString()},
179 {"type", description.typeString()},
180 {"description", std::string(description)}};
181
182 std::string m = message.dump();
183 return Write(m.c_str(), m.size());
184}
CIceSignalWebSocket(QObject *parent=nullptr)
The ICE signal interface class.
Definition IceSignal.h:26
void sigOffer(const QString &fromUser, const QString &toUser, const QString &channelId, const QString &type, const QString &sdp)
sigOffer
void sigDescription(const QString &fromUser, const QString &toUser, const QString &channelId, const QString &type, const QString &sdp)
sigDescription