forked from niv/pusher-websocket-cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pushcpp.h
222 lines (193 loc) · 5.6 KB
/
pushcpp.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#pragma once
#include <string>
#include <set>
#include <unordered_map>
#include <vector>
#include <thread>
class pushcpp
{
public:
enum class ConnectionEvent {
CONNECTED = 0,
DISCONNECTED = 1
};
typedef void (*ConnectionEventHandler)(
const ConnectionEvent ce
);
typedef void (*ErrorEventHandler)(
const int code,
const std::string &message
);
typedef void (*ChannelEventHandler)(
const std::string &channel,
const std::string &event,
const std::string &eventData);
typedef void (*ChannelPresenceHandler)(
const std::string &channel
);
/**
* Return this for authentication requests.
*/
struct ChannelAuthentication {
std::string auth;
std::string channelData;
};
/**
* Called when we want authentication data.
* You need to do a pusher API request here as described on
* https://pusher.com/docs/auth_signatures. This probably involves
* making a HTTP request to your custom backend, and as such it is
* left as an exercise to the reader!
*
* Blocking inside this function will block either the subscribe()
* method call that originates this, or the pusher event thread.
* This might change in the future.
*/
typedef ChannelAuthentication(*ChannelAuthHandler)(
const std::string &socketId,
const std::string &channel
);
struct ChannelData {
bool subscribed = false;
ChannelAuthHandler authHandler;
std::set<ChannelEventHandler> eventHandlers;
std::set<std::string> presenceMemberIds;
void clear()
{
subscribed = false;
presenceMemberIds.clear();
}
};
/**
* Sets up this client and configures it.
* This does not connect yet.
*/
pushcpp(
const std::string &appKey,
ConnectionEventHandler ch = NULL,
ErrorEventHandler eh = NULL
);
/**
* Connects to the configured remote URL.
*
* This needs to be called once, and it will reconnect
* transparently on socket failure. This starts a new thread
* in the background.
*/
void connect();
/**
* Disconnects from Pusher, stopping the event thread.
*
* This does NOT invalidate subscriptions; on connect(), they will
* be re-subscribed.
*
* Setting wait to true will wait until the socket is closed.
*/
void disconnect(bool wait = false);
/**
* Join against the running thread after calling connect().
* A helper for testing this library or if you want to use it standalone
* by blocking on the event loop.
*/
void join();
/**
* Subscribe to a channel. The given event handler
* will be called when a channel receives a message.
*
* You can call this at any time, no matter the connection state.
* Channels will be automatically resubscribed to on reconnect.
*
* Repeatedly subscribing to the same channel will do nothing.
*
* Will return true if the subscription was sent out immediately (since
* we were connected), false otherwise.
*/
bool subscribe(
const std::string &channel,
/**
* This handler receives all channel events, including
* internal ones, in case you want to act on them.
*/
ChannelEventHandler event,
/**
* This is called for authentication requests as described
* above. presence- and private- channels require this.
*/
ChannelAuthHandler auth = NULL
);
/**
* Unsubscribes you from this channel.
* This will immediately destroy all associated data.
*/
void unsubscribe(const std::string &channel);
/**
* Triggers a client event on the given channel.
* The library adds "client-" in front of the event name if it's missing,
* so you can leave it off if you are lazy.
*
* Please note that as per the pusher spec, channel
* needs to be a "private-" or "presence-" channel.
*/
bool trigger(
const std::string &channel,
const std::string &event,
const std::string &data
);
/**
* Sends a event object to Pusher. data can be any binary data; it will
* be transparently en/decoded.
* Channel and data can be "".
* This is mostly for internal use.
* Will return true if the message was sent, false otherwise. */
bool send(
const std::string &channel,
const std::string &event,
const std::string &data
);
/**
* Send some raw data over the websocket. For pusher, this needs
* to be valid json - see https://pusher.com/docs/pusher_protocol
* This is mostly for internal use.
* Will return true if the message was sent, false otherwise. */
bool sendRaw(const std::string &raw);
/**
* Returns true if we are currently connected.
*/
bool connected() const;
/**
* Returns a set of our currently subscribed-to channels.
* If you only want channels we received confirmation to on,
* pass confirmedOnly = true.
*/
std::unordered_map<std::string, ChannelData>
subscriptions(bool confirmedOnly = true) const;
const std::string & socketId() const
{
return m_socketId;
}
private:
// Dont allow copying.
// No point in opening a second connection, is there?
pushcpp(const pushcpp&);
pushcpp& operator=(const pushcpp&);
std::string m_url;
bool m_wantDisconnect = false;
std::string m_socketId;
// The current connection, if any!
void *m_websocket = NULL;
std::thread * m_eventThread = NULL;
void EventThread();
void WS_Dispatch(const std::string & message);
/* Send a subscription request to Pusher. You do not need to call this
* yourself; use subscribe() instead!
* Will return true if the message was sent, false otherwise. */
bool sendSubscription(
bool subscribe,
const std::string &channel
);
ErrorEventHandler m_errorEventHandler;
ConnectionEventHandler m_connectionEventHandler;
// The complete list of channels we (want to) subscribe to.
// This includes channels we were rejected from.
std::unordered_map<std::string, ChannelData> m_channelData;
};