16 #include "TTWebSocket.h"
21 static void *ws_server_thread(
void *parm)
24 struct mg_connection *conn = ws_conn[wsd].conn;
28 while(!ws_conn[wsd].closing) {
29 std::this_thread::sleep_for(std::chrono::milliseconds(100));
33 if (timer%100 == 0 && !ws_conn[wsd].closing)
34 mg_websocket_write(conn, WEBSOCKET_OPCODE_PING, NULL, 0);
38 ws_conn[wsd].conn = NULL;
39 ws_conn[wsd].update = 0;
40 ws_conn[wsd].closing = 2;
49 static int websocket_connect_handler(
const struct mg_connection *conn)
53 fprintf(stderr,
"websocket connect handler\n");
55 for(i=0; i < CONNECTIONS; ++i) {
56 if (ws_conn[i].conn == NULL) {
57 ws_conn[i].conn = (
struct mg_connection *)conn;
58 ws_conn[i].closing = 0;
59 ws_conn[i].update = 0;
63 if (i >= CONNECTIONS) {
64 fprintf(stderr,
"websocket refused connection: Max connections exceeded\n");
73 static void websocket_ready_handler(
struct mg_connection *conn)
77 fprintf(stderr,
"websocket ready handler\n");
79 for(i=0; i < CONNECTIONS; ++i) {
80 if (ws_conn[i].conn == conn) {
81 fprintf(stderr,
"websocket start server %d\n", i);
82 mg_start_thread(ws_server_thread, (
void *)(
long)i);
90 static void websocket_close_handler(
struct mg_connection *conn)
96 for(i=0; i < CONNECTIONS; ++i) {
97 if (ws_conn[i].conn == conn) {
98 fprintf(stderr,
"websocket close server %d\n", i);
99 ws_conn[i].closing = 1;
108 static int websocket_data_handler(
struct mg_connection *conn,
int flags,
109 char *data,
size_t data_len)
115 for(i=0; i < CONNECTIONS; ++i) {
116 if (ws_conn[i].conn == conn) {
121 if (i >= CONNECTIONS) {
122 fprintf(stderr,
"websocket received websocket data from unknown connection\n");
126 std::string s1 = data;
127 std::string s2 =
"set";
128 std::string s3 =
"get";
129 std::string s4 =
"namespace";
130 std::string s5 =
"listen";
131 std::size_t found1 = s1.find(s2);
132 std::size_t found2 = s1.find(s3);
133 std::size_t found3 = s1.find(s4);
134 std::size_t found4 = s1.find(s5);
139 case WEBSOCKET_OPCODE_CONTINUATION:
140 fprintf(stderr,
"websocket receive CONTINUATION...\n");
142 case WEBSOCKET_OPCODE_TEXT:
143 fprintf(stderr,
"websocket receive : %-.*s\n", (
int)data_len, data);
146 mLastConnection = conn;
149 if (found1 == std::string::npos && found2 == std::string::npos && found3 == std::string::npos && found4 == std::string::npos)
150 for(i=0; i < CONNECTIONS; ++i) {
151 if (ws_conn[i].conn && i != wsd)
152 mg_websocket_write(ws_conn[i].conn, WEBSOCKET_OPCODE_TEXT, data, data_len);
157 if (found1 != std::string::npos)
158 for(i=0; i < CONNECTIONS; ++i) {
159 if (ws_conn[i].conn && i != wsd)
160 mg_websocket_write(ws_conn[i].conn, WEBSOCKET_OPCODE_TEXT, data, data_len);
164 data[data_len] =
'\0';
167 receivedMessage.
clear();
169 ((
TTWebSocketPtr)(mg_get_request_info(conn)->user_data))->mOwner->sendMessage(
TTSymbol(
"WebSocketReceive"), receivedMessage, kTTValNONE);
172 case WEBSOCKET_OPCODE_BINARY:
173 fprintf(stderr,
"websocket receive BINARY...\n");
175 case WEBSOCKET_OPCODE_CONNECTION_CLOSE:
176 fprintf(stderr,
"websocket receive CLOSE...\n");
178 if (!ws_conn[wsd].closing) {
179 mg_websocket_write(conn, WEBSOCKET_OPCODE_CONNECTION_CLOSE, data, data_len);
180 ws_conn[wsd].closing = 1;
184 case WEBSOCKET_OPCODE_PING:
186 mg_websocket_write(conn, WEBSOCKET_OPCODE_PONG, data, data_len);
188 case WEBSOCKET_OPCODE_PONG:
192 fprintf(stderr,
"websocket Unknown flags: %02x\n", flags);
205 mHtmlPath = htmlPath;
212 TTWebSocket::~TTWebSocket()
220 sprintf(portString,
"%d", mPort);
222 char server_name[40];
223 struct mg_callbacks callbacks;
224 const char *options[] = {
225 "listening_ports", portString,
226 "document_root", mHtmlPath,
231 snprintf(server_name,
sizeof(server_name),
232 "Civetweb websocket server v. %s",
235 memset(&callbacks, 0,
sizeof(callbacks));
236 callbacks.websocket_connect = websocket_connect_handler;
237 callbacks.websocket_ready = websocket_ready_handler;
238 callbacks.websocket_data = websocket_data_handler;
239 callbacks.connection_close = websocket_close_handler;
241 mContext = mg_start(&callbacks,
this, options);
245 printf(
"%s started on port(s) %s with web root [%s]\n",
246 server_name, mg_get_option(mContext,
"listening_ports"),
247 mg_get_option(mContext,
"document_root"));
257 if (mLastConnection) {
258 int result = mg_websocket_write(mLastConnection, WEBSOCKET_OPCODE_TEXT, message.
c_str(), message.string().
size());
std::uint16_t TTUInt16
16 bit unsigned integer
Create a websocket server.
TTWebSocket()
Create a socket to send websocket messages.
Base class for all first-class Jamoma objects.
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
TTObjectBasePtr mOwner
The object that instantiated this socket and will receive notifications.
void TTFOUNDATION_EXPORT TTLogError(TTImmutableCString message,...)
Platform and host independent method for posting errors.
const char * c_str() const
Return a pointer to the internal string as a C-string.
TTErr bind()
Bind websocket server.
void clear()
Clear all values from the vector, leaving with size of 0.
Something went wrong, but what exactly is not known. Typically used for context-specific problems...
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
size_t size() const
Find out the length of a string.
The TTString class is used to represent a string.
[doxygenAppendixC_copyExample]
TTErr SendMessage(TTSymbol &message)
Send message.