catalinux / Conn (public) (License: LGPLv2) (since 2016-03-01) (hash sha1)
Net library for easy building ipv4/ipv6 network daemons/clients
List of commits:
Subject Hash Author Date (UTC)
wsdemo improvements 3eb3efd007fc9240ea39fabcdb4729d1367ebad2 Catalin(ux) M. BOIE 2018-04-13 22:47:24
wsdemo added 2baae01f2409496f990b6d673013b66286f0a5af Catalin(ux) M. BOIE 2018-04-02 21:41:40
Various small stuff 0c551268be734dd68a59426315abfc6ef776c60a Catalin(ux) M. BOIE 2018-04-02 21:40:49
More debugging for websocket parsing 66ccde632b280f1aa450610e6b671464b7e56451 Catalin(ux) M. BOIE 2018-04-02 21:39:23
Raise to 4096 to buffer for logging a59dee1fdfe087ff13e4c7012fe29f8da99ad75c Catalin(ux) M. BOIE 2018-04-02 21:38:11
Bump version 9b635cebfffdd6971eefef0ebad395e21684bb8a Catalin(ux) M. BOIE 2018-01-13 18:07:12
Added some more compile flags and websocket1 helper files. fce47295946106956fb70da77244d77ffca09423 Catalin(ux) M. BOIE 2018-01-13 18:03:46
Lots of changes everywhere 91b9113e8f92db07c079c005273683f2e868910c Catalin(ux) M. BOIE 2018-01-12 19:06:04
Require openssl (for websocket) b4b34eb88f38bfd421187da76611cc54476d7309 Catalin(ux) M. BOIE 2017-12-30 23:44:50
Very important fixes 01e33f06a5cdc52fb3795158fd838fcca7055dda Catalin(ux) M. BOIE 2017-12-30 23:39:17
Bump version to 1.0.37 54e8f3bcaf7f7e096c454563039a545a4abb1bf0 Catalin(ux) M. BOIE 2017-12-30 22:13:12
Lots of small fixes 4894de0472e571b8c78294de527bf70089096545 Catalin(ux) M. BOIE 2017-12-30 22:11:09
Checkpoint b6bf45330f046da40d762b6fd10d1bb97bc40036 Catalin(ux) M. BOIE 2017-12-28 00:13:09
Fixed libConn*.so instalation. df1bef9190d30dd11fcd150b41810ce18278b74f Catalin(ux) M. BOIE 2015-04-25 14:43:37
libConn1.so was not included in spec file. dd99625a7fb70d66fa5a91371fb4d2eaf7a4f23d Catalin(ux) M. BOIE 2015-04-25 14:39:32
Small fixes for build system. ab12cbbe149933cbf1b9a9900be1a45d63ee0b29 Catalin(ux) M. BOIE 2015-04-25 14:17:14
Build fixes e7521468199d4da53461fb0c1ffa08e1913c1e9f Catalin(ux) M. BOIE 2015-04-24 19:18:42
Checkpoint before switching to processes not threads de43b387557dde215ab1210838d396e7e7b22c4f Catalin(ux) M. BOIE 2015-01-14 04:13:00
Wpools work now\! f875d6bea1777c3a290bf9bb1aa047f26c935a63 Catalin(ux) M. BOIE 2013-11-13 20:51:13
WIP 1d246f2130d4acf8c267e82051b250a623da6870 Catalin(ux) M. BOIE 2013-10-16 19:57:04
Commit 3eb3efd007fc9240ea39fabcdb4729d1367ebad2 - wsdemo improvements
Author: Catalin(ux) M. BOIE
Author date (UTC): 2018-04-13 22:47
Committer name: Catalin(ux) M. BOIE
Committer date (UTC): 2018-04-13 22:47
Parent(s): 2baae01f2409496f990b6d673013b66286f0a5af
Signing key:
Tree: 3752fec7e3d507b8350d6f62c6783ce65d9ff12d
File Lines added Lines deleted
.gitignore 1 0
examples/wsdemo.c 502 118
examples/wsdemo.data/main.css 4 5
examples/wsdemo.data/main.js 3 2
File .gitignore changed (mode: 100644) (index f46bab4..30a78e3)
... ... duilder_release
15 15 *.pcap *.pcap
16 16 *.ltrace *.ltrace
17 17 History.size History.size
18 wsdemo
File examples/wsdemo.c changed (mode: 100644) (index a047725..94e11ed)
... ... struct priv {
25 25 unsigned int x, y; // screen size unsigned int x, y; // screen size
26 26
27 27 unsigned int main_init:1; unsigned int main_init:1;
28 unsigned int progress_bar1_init:1;
28 unsigned int per1_init:1;
29 unsigned int per2_init:1;
29 30 unsigned int load1_init:1; unsigned int load1_init:1;
30 31 unsigned int arc1_init:1; unsigned int arc1_init:1;
31 32 unsigned int band1_init:1; unsigned int band1_init:1;
33 unsigned int cyl1_init:1;
34 unsigned int pie1_init:1;
35 unsigned int bar1_init:1;
32 36
33 unsigned char progress_bar1_percent;
37 unsigned char per1_percent;
38 unsigned char per2_percent;
34 39
35 40 unsigned char arc1_count; unsigned char arc1_count;
36
41 unsigned char cyl1_count;
42 unsigned char pie1_count;
43 unsigned char bar1_count;
37 44 }; };
38 45
39 46 /* load is global */ /* load is global */
40 47 static unsigned char load_current; static unsigned char load_current;
41 48 static unsigned char load[100]; static unsigned char load[100];
49 static time_t load_last; // when the last value was updated
50
51 /* bandwidth is global */
52 #define BAND_VALUES 200
53 static unsigned char band_current = BAND_VALUES - 1;
54 static unsigned char band[2][BAND_VALUES];
55 static time_t band_last; // when the last value was updated
56 static int band_up = 30, band_down = 30; // fake start values
42 57
43 58 struct Clients struct Clients
44 59 { {
 
... ... struct Clients
48 63 static struct Clients *Clients_head, *Clients_tail; static struct Clients *Clients_head, *Clients_tail;
49 64
50 65
66 /*
67 * Update global values
68 */
69 static void update_global(void)
70 {
71 struct timeval now;
72
73 gettimeofday(&now, NULL);
74
75 if (load_last + 1 < now.tv_sec) {
76 double avg;
77
78 getloadavg(&avg, 1); avg *= 100;
79 load_current = (load_current + 1) % sizeof(load);
80 load[load_current] = avg;
81 load_last = now.tv_sec;
82 }
83
84 if (band_last + 1 < now.tv_sec) {
85 int sign;
86
87 sign = random() % 2 == 0 ? -1 : 1;
88 band_up += (random() % 10) * sign;
89 if (band_up < 0)
90 band_up = 0;
91 if (band_up > 40)
92 band_up = 40;
93
94 sign = random() % 2 == 0 ? -1 : 1;
95 band_down += (random() % 10) * sign;
96 if (band_down < 0)
97 band_down = 0;
98 if (band_down > 40)
99 band_down = 40;
100 band_current = (band_current + 1) % BAND_VALUES;
101
102 Log(0, "DEBUG: band: add index=%u %hhu %hhu\n",
103 band_current, band_up, band_down);
104
105 band[0][band_current] = band_up;
106 band[1][band_current] = band_down;
107 band_last = now.tv_sec;
108 }
109 }
110
51 111 static void push_code(struct Conn *C, const char *code) static void push_code(struct Conn *C, const char *code)
52 112 { {
53 113 const char *s; const char *s;
 
... ... static void notify(struct Conn *C, const char *format, ...)
94 154 json_object_put(j); json_object_put(j);
95 155 } }
96 156
97 static void progress_bar1(struct Conn *C)
157 static void per1(struct Conn *C)
98 158 { {
99 159 struct priv *p; struct priv *p;
100 160 char code[256]; char code[256];
101 161
102 162 p = Conn_get_private(C); p = Conn_get_private(C);
103 if (!p->progress_bar1_init) {
163 if (!p->per1_init) {
104 164 const char *code = const char *code =
105 "window.wsdemo.progress_bar1_update = function(a) {\n"
106 " d = document.getElementById('progress_bar1');\n"
165 "window.wsdemo.per1_update = function(a) {\n"
166 " var d = document.getElementById('per1');\n"
107 167 " d.style.width = String(a) + 'px';\n" " d.style.width = String(a) + 'px';\n"
108 168 "}\n"; "}\n";
109 169 push_code(C, code); push_code(C, code);
110 p->progress_bar1_init = 1;
170 p->per1_init = 1;
111 171 } }
112 172
113 173 snprintf(code, sizeof(code), snprintf(code, sizeof(code),
114 "window.wsdemo.progress_bar1_update(%hhu)",
115 p->progress_bar1_percent);
116 p->progress_bar1_percent = (p->progress_bar1_percent + 1) % 100;
174 "window.wsdemo.per1_update(%hhu)",
175 p->per1_percent);
176 p->per1_percent = (p->per1_percent + 1) % 100;
117 177 push_code(C, code); push_code(C, code);
118 178 } }
119 179
120 static void progress_bar2(struct Conn *C)
180 static void per2(struct Conn *C)
121 181 { {
122 static unsigned char percent = 0;
123 char code[512];
182 struct priv *p;
183 char code[256];
124 184
125 snprintf(code, sizeof(code),
126 "d = document.getElementById('progress_bar2')"
127 "; d.style.width = String(%hhu) + 'px'",
128 percent);
129 percent += 5;
130 percent %= 100;
185 p = Conn_get_private(C);
186 if (!p->per2_init) {
187 const char *u =
188 "window.wsdemo.per2_update = function(a) {\n"
189 " var d = document.getElementById('per2');\n"
190 " d.setAttribute('width', a);\n"
191 "}\n";
192 push_code(C, u);
193 p->per2_init = 1;
194 }
131 195
196 snprintf(code, sizeof(code),
197 "window.wsdemo.per2_update(%hhu)",
198 p->per2_percent);
199 p->per2_percent = (p->per2_percent + 1) % 100;
132 200 push_code(C, code); push_code(C, code);
133 201 } }
134 202
 
... ... static void load1(struct Conn *C)
137 205 struct priv *p; struct priv *p;
138 206 char code[256]; char code[256];
139 207 unsigned int slots; unsigned int slots;
208 unsigned char i;
140 209
141 210 p = Conn_get_private(C); p = Conn_get_private(C);
211 slots = p->x - 40 > sizeof(load) ? sizeof(load) : p->x - 40;
142 212
143 213 if (!p->load1_init) { if (!p->load1_init) {
144 const char *code =
214 const char *u =
145 215 "window.wsdemo.load1_update = function(id, slots, width, space, load) {\n" "window.wsdemo.load1_update = function(id, slots, width, space, load) {\n"
146 216 " var svgns = \"http://www.w3.org/2000/svg\";\n" " var svgns = \"http://www.w3.org/2000/svg\";\n"
147 217 "" ""
148 " d = document.getElementById('load1_container');\n"
218 " var d = document.getElementById('load1_container');\n"
149 219 " d.setAttribute('width', slots);\n" " d.setAttribute('width', slots);\n"
150 220 "" ""
151 221 " d = document.getElementById(id);\n" " d = document.getElementById(id);\n"
 
... ... static void load1(struct Conn *C)
172 242 " var div = document.getElementById(id + '_text');\n" " var div = document.getElementById(id + '_text');\n"
173 243 " div.innerHTML = 'Load: ' + load;\n" " div.innerHTML = 'Load: ' + load;\n"
174 244 "}\n"; "}\n";
175 push_code(C, code);
245 push_code(C, u);
246
247 // Sending previous values
248 for (i = 0; i < sizeof(load) - 1; i++) {
249 snprintf(code, sizeof(code),
250 "window.wsdemo.load1_update('load1', %u, 1, 0.2, %hhu);\n",
251 slots, load[(load_current + 1 + i) % sizeof(load)]);
252 push_code(C, code);
253 }
254
176 255 p->load1_init = 1; p->load1_init = 1;
177 // TODO: send previous values
178 256 } }
179 257
180 258 // Send current value (id, slots, width, space, last_load) // Send current value (id, slots, width, space, last_load)
181 slots = p->x - 40 > 100 ? 100 : p->x - 40;
182 259 snprintf(code, sizeof(code), snprintf(code, sizeof(code),
183 260 "window.wsdemo.load1_update('load1', %u, 1, 0.2, %hhu);\n", "window.wsdemo.load1_update('load1', %u, 1, 0.2, %hhu);\n",
184 261 slots, load[load_current]); slots, load[load_current]);
 
... ... static void band1(struct Conn *C)
189 266 { {
190 267 struct priv *p; struct priv *p;
191 268 char code[256]; char code[256];
192 static int up = 30, down = 30;
193 int sign;
194 269 unsigned int slots; unsigned int slots;
270 unsigned char pos;
195 271
196 272 p = Conn_get_private(C); p = Conn_get_private(C);
273 slots = p->x - 40 > BAND_VALUES ? BAND_VALUES : p->x - 40;
274
197 275 if (!p->band1_init) { if (!p->band1_init) {
198 const char *code =
276 unsigned int i;
277
278 const char *u =
199 279 "window.wsdemo.band1_update = function (slots, up, down) {\n" "window.wsdemo.band1_update = function (slots, up, down) {\n"
200 280 " var svgns = 'http://www.w3.org/2000/svg';\n" " var svgns = 'http://www.w3.org/2000/svg';\n"
201 281 "" ""
202 " d = document.getElementById('band1_container');\n"
203 " console.log('DEBUG: band1_container width=' + slots);\n"
282 " var d = document.getElementById('band1_container');\n"
204 283 " d.setAttribute('width', slots);\n" " d.setAttribute('width', slots);\n"
205 284 "" ""
206 285 " d = document.getElementById('band1_line');\n" " d = document.getElementById('band1_line');\n"
 
... ... static void band1(struct Conn *C)
241 320 " d.children[i + 1].setAttributeNS(null, 'x2', slots - len / 2 + i / 2);\n" " d.children[i + 1].setAttributeNS(null, 'x2', slots - len / 2 + i / 2);\n"
242 321 " }\n" " }\n"
243 322 "}\n"; "}\n";
244 push_code(C, code);
323 push_code(C, u);
324
325 // Sending previous values
326 for (i = 0; i < BAND_VALUES - 1; i++) {
327 pos = (band_current + 1 + i) % BAND_VALUES;
328 snprintf(code, sizeof(code),
329 "window.wsdemo.band1_update(%u, %hhu, %hhu);\n",
330 slots, band[0][pos], band[1][pos]);
331 push_code(C, code);
332 Log(0, "DEBUG: band: prev: i=%u %u %hhu %hhu\n",
333 i, pos, band[0][pos], band[1][pos]);
334 }
335
245 336 p->band1_init = 1; p->band1_init = 1;
246 337 } }
247 338
248 sign = random() % 2 == 0 ? -1 : 1;
249 up += (random() % 10) * sign;
250 if (up < 0)
251 up = 0;
252 if (up > 40)
253 up = 40;
254
255 sign = random() % 2 == 0 ? -1 : 1;
256 down += (random() % 10) * sign;
257 if (down < 0)
258 down = 0;
259 if (down > 40)
260 down = 40;
261
262 slots = p->x - 40 > 200 ? 200 : p->x - 40;
339 pos = band_current;
263 340 snprintf(code, sizeof(code), snprintf(code, sizeof(code),
264 "window.wsdemo.band1_update(%u, %u, %u)",
265 slots, up, down);
341 "window.wsdemo.band1_update(%u, %hhu, %hhu)",
342 slots, band[0][pos], band[1][pos]);
266 343 push_code(C, code); push_code(C, code);
344 Log(0, "DEBUG: band: curr: %u %hhu %hhu\n",
345 pos, band[0][pos], band[1][pos]);
267 346 } }
268 347
269 348 static void arc1(struct Conn *C) static void arc1(struct Conn *C)
 
... ... static void arc1(struct Conn *C)
276 355
277 356 p = Conn_get_private(C); p = Conn_get_private(C);
278 357 if (!p->arc1_init) { if (!p->arc1_init) {
279 snprintf(code, sizeof(code),
280 "window.wsdemo.arc1_update = function(a) {\n"
281 " // compute sum\n"
282 " var sum = 0;\n"
283 ""
284 " for (i = 0; i < a.length; i++)\n"
285 " sum += a[i].value;\n"
286 ""
287 " d = document.getElementById('arc1');\n"
288 " t = document.getElementById('arc1_text');\n"
289 ""
290 " // TODO: we must respect first point to allow user to position the elements!\n"
291 " last_x = 10; last_y = 50; last_angle = Math.PI;\n"
292 " for (i = 0; i < a.length; i++) {\n"
293 " //console.log('i=' + i + ' last_x=' + last_x + ' last_y=' + last_y + ' last_angle=' + last_angle + ' value=' + a[i].value + ' per=' + a[i].value * 100 / sum + '%%');\n"
294 ""
295 " m = d.children[i].pathSegList[0];\n"
296 " m.x = last_x; m.y = last_y;\n"
297 ""
298 " c = d.children[i].pathSegList[1];\n"
299 " angle = a[i].value * 2 * Math.PI / sum;\n"
300 " //console.log('angle[' + i + ']=' + angle);\n"
301 " if (angle > Math.PI) {\n"
302 " c.largeArcFlag = true;\n"
303 " } else {\n"
304 " c.largeArcFlag = false;\n"
305 " }\n"
306 " c.x = (50 - last_x) + 40 * Math.cos(last_angle + angle);\n"
307 " c.y = (50 - last_y) + 40 * Math.sin(last_angle + angle);\n"
308 " //console.log('c.x/y[' + i + ']=' + c.x + '/' + c.y);\n"
309 " last_x += c.x; last_y += c.y; last_angle += angle;\n"
310 " t.children[i].innerHTML = a[i].name + ': ' + parseInt(a[i].value * 100 / sum) + '%%';\n"
311 " }\n"
312 " for (; i < 5; i++) {\n"
313 " c = d.children[i].pathSegList[1];\n"
314 " c.x = 0; c.y = 0;\n"
315 " t.children[i].innerHTML = '';\n"
316 " }\n"
317 "}");
318 push_code(C, code);
358 const char *u =
359 "window.wsdemo.arc1_update = function(a) {\n"
360 " // compute sum\n"
361 " var sum = 0;\n"
362 " var i;\n"
363 ""
364 " for (i = 0; i < a.length; i++)\n"
365 " sum += a[i].value;\n"
366 ""
367 " var d = document.getElementById('arc1');\n"
368 " var t = document.getElementById('arc1_text');\n"
369 ""
370 " // TODO: we must respect first point to allow user to position the elements!\n"
371 " var last_x = 10; var last_y = 50; var last_angle = Math.PI;\n"
372 " for (i = 0; i < a.length; i++) {\n"
373 " var m = d.children[i].pathSegList[0];\n"
374 " m.x = last_x; m.y = last_y;\n"
375 ""
376 " var c = d.children[i].pathSegList[1];\n"
377 " angle = a[i].value * 2 * Math.PI / sum;\n"
378 " if (angle > Math.PI) {\n"
379 " c.largeArcFlag = true;\n"
380 " } else {\n"
381 " c.largeArcFlag = false;\n"
382 " }\n"
383 " c.x = (50 - last_x) + 40 * Math.cos(last_angle + angle);\n"
384 " c.y = (50 - last_y) + 40 * Math.sin(last_angle + angle);\n"
385 " last_x += c.x; last_y += c.y; last_angle += angle;\n"
386 " t.children[i].innerHTML = a[i].name + ': ' + parseInt(a[i].value * 100 / sum) + '%%';\n"
387 " }\n"
388 " for (; i < 5; i++) {\n"
389 " var c = d.children[i].pathSegList[1];\n"
390 " c.x = 0; c.y = 0;\n"
391 " t.children[i].innerHTML = '';\n"
392 " }\n"
393 "}";
394 push_code(C, u);
319 395 p->arc1_init = 1; p->arc1_init = 1;
320 396 p->arc1_count = 4; p->arc1_count = 4;
321 397 } }
322 398
323 399 p->arc1_count++; p->arc1_count++;
324 if (p->arc1_count < 5)
400 p->arc1_count %= 5;
401 if (p->arc1_count > 0)
325 402 return; return;
326 403
327 404 strcpy(vars, "[ "); add = ""; strcpy(vars, "[ "); add = "";
 
... ... static void arc1(struct Conn *C)
340 417
341 418 snprintf(code, sizeof(code), "window.wsdemo.arc1_update(%s)", vars); snprintf(code, sizeof(code), "window.wsdemo.arc1_update(%s)", vars);
342 419 push_code(C, code); push_code(C, code);
343 p->arc1_count = 0;
420 }
421
422 static void bar1(struct Conn *C)
423 {
424 struct priv *p;
425 char code[4096];
426 char *names[] = { "Bar 1", "Bar 2", "Bar 3", "Bar 4", "Bar 5", "Bar 6" };
427 char vars[512], *add;
428 unsigned char i, nr;
429
430 // https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths
431 p = Conn_get_private(C);
432 if (!p->bar1_init) {
433 const char *u =
434 "window.wsdemo.bar1_update = function(a, width, depth) {\n"
435 " var svgns = \"http://www.w3.org/2000/svg\";\n"
436 " var i, bbox, space = width - a.length;\n"
437 ""
438 " var d = document.getElementById('bar1');\n"
439 " var t = document.getElementById('bar1_text');\n"
440 " var tv = document.getElementById('bar1_values');\n"
441 ""
442 " var last_x = (100 - a.length * width - (a.length - 1) * space) / 2;\n"
443 " for (i = 0; i < a.length; i++) {\n"
444 " if (d.children[i] == null) {\n"
445 " var path = document.createElementNS(svgns, 'path');\n"
446 " path.setAttribute('stroke', 'black');\n"
447 " path.setAttribute('stroke-width', '0.1');\n"
448 " path.setAttribute('d', 'M0 0');\n"
449 " d.appendChild(path);\n"
450 ""
451 " var text = document.createElementNS(svgns, 'text');\n"
452 " text.setAttribute('y', 90);\n"
453 " text.setAttribute('font-size', 3);\n"
454 " t.appendChild(text);\n"
455 ""
456 " text = document.createElementNS(svgns, 'text');\n"
457 " text.setAttribute('y', 94);\n"
458 " text.setAttribute('font-size', 3);\n"
459 " text.setAttribute('fill', '#000');\n"
460 " tv.appendChild(text);\n"
461 " }\n"
462 ""
463 " var v = a[i].value;\n"
464 " var center = last_x + width / 2;\n"
465 ""
466 " var m = d.children[i];\n"
467 " m.setAttribute('fill', a[i].color);\n"
468 " m.setAttribute('d',\n"
469 " 'M' + (last_x + width) + ',' + (85 - v)\n"
470 " + ' v' + v + ' h-' + width + ' v-' + v + ' z'\n"
471 " + ' l' + depth + ',-' + depth + ' v' + v + ' l-' + depth + ',' + depth + ' z'\n"
472 " + ' h-' + width + ' l' + depth + ',-' + depth + ' h' + width + ' z');\n"
473 ""
474 " t.children[i].setAttribute('fill', a[i].color);\n"
475 " t.children[i].innerHTML = a[i].name;\n"
476 " bbox = t.children[i].getBBox();\n"
477 " t.children[i].setAttribute('x', center - bbox.width / 2);\n"
478 ""
479 " tv.children[i].innerHTML = v;\n"
480 " bbox = tv.children[i].getBBox();\n"
481 " tv.children[i].setAttribute('x', center - bbox.width / 2);\n"
482 ""
483 " last_x += width + space;\n"
484 " }\n"
485 " while (d.children[i] != null) {\n"
486 " d.removeChild(d.children[i]);\n"
487 " t.removeChild(t.children[i]);\n"
488 " tv.removeChild(tv.children[i]);\n"
489 " }\n"
490 "}";
491 push_code(C, u);
492 p->bar1_init = 1;
493 p->bar1_count = 4;
494 }
495
496 p->bar1_count++;
497 p->bar1_count %= 5;
498 if (p->bar1_count > 0)
499 return;
500
501 strcpy(vars, "[ "); add = "";
502 nr = 2 + random() % 5;
503 for (i = 0; i < nr; i++) {
504 char tmp[64];
505 unsigned int v;
506
507 v = 10 + (unsigned int) random() % 60;
508 snprintf(tmp, sizeof(tmp), "%s{ name:\"%s\", value:%u, color:\"#%06lx\" }",
509 add, names[i], v, random() % 0x1000000);
510 strcat(vars, tmp);
511 add = ", ";
512 }
513 strcat(vars, "]");
514
515 snprintf(code, sizeof(code), "window.wsdemo.bar1_update(%s, %ld, %ld)",
516 vars, 10 + random() % (8 - nr), 3 + random() % (12 - nr));
517 push_code(C, code);
518 }
519
520 static void cyl1(struct Conn *C)
521 {
522 struct priv *p;
523 char code[4096];
524 char *colors;
525
526 p = Conn_get_private(C);
527 if (!p->cyl1_init) {
528 const char *u =
529 "window.wsdemo.cyl1_update = function(a, colors) {\n"
530 " var i;\n"
531 " var canvas = document.getElementById('cyl1');\n"
532 " var ctx = canvas.getContext('2d');\n"
533 " ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n"
534 " ctx.lineWidth = 1;\n"
535 ""
536 " // draw big rectangle\n"
537 " ctx.beginPath();\n"
538 " ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height);\n"
539 " ctx.stroke();\n"
540 ""
541 " // draw some lines\n"
542 " for (i = 0; i < 100; i += 10) {\n"
543 " ctx.beginPath();\n"
544 " ctx.moveTo(0, 99.5 - i);\n"
545 " ctx.lineTo(100, 99.5 - i);\n"
546 " ctx.stroke();\n"
547 " }\n"
548 ""
549 " ctx.save();\n"
550 " ctx.shadowColor = '#444';\n"
551 " ctx.shadowBlur = 2;\n"
552 " ctx.shadowOffsetX = 1;\n"
553 " ctx.shadowOffsetY = 1;\n"
554 " var last_x = 7;\n"
555 " for (i = 0; i < a.length; i++) {\n"
556 " // define gradient\n"
557 " var g = ctx.createLinearGradient(last_x, 0, last_x + 10, 0);\n"
558 " g.addColorStop(0, colors[i].s);\n"
559 " g.addColorStop(0.5, colors[i].m);\n"
560 " g.addColorStop(1, colors[i].s);\n"
561 " ctx.fillStyle = g;\n"
562 ""
563 " ctx.fillRect(last_x, 99 - a[i], 10, a[i]);\n"
564 " last_x += 15;\n"
565 " }\n"
566 " ctx.restore();\n"
567 "}";
568 push_code(C, u);
569 p->cyl1_init = 1;
570 }
571
572 p->cyl1_count++;
573 p->cyl1_count %= 4;
574 if (p->cyl1_count != 1)
575 return;
576
577 colors = "["
578 " { 's':'#4bc', 'm':'#5ff' }"
579 ", { 's':'#c4b', 'm':'#f5f' }"
580 ", { 's':'#bc4', 'm':'#ff5' }"
581 ", { 's':'#46d', 'm':'#5af' }"
582 ", { 's':'#e20', 'm':'#faa' }"
583 ", { 's':'#4c4', 'm':'#5f5' }"
584 " ]";
585
586 snprintf(code, sizeof(code),
587 "window.wsdemo.cyl1_update([%lu, %lu, %lu, %lu, %lu, %lu], %s)",
588 10 + random() % 80, 10 + random() % 80, 10 + random() % 80,
589 10 + random() % 80, 10 + random() % 80, 10 + random() % 80,
590 colors);
591 push_code(C, code);
592 }
593
594 static void pie1(struct Conn *C)
595 {
596 struct priv *p;
597 char code[4096];
598 char *names[] = { "Option 1", "Option 2", "Option 3", "Option 4", "Option 5" };
599 char vars[512], *add;
600 unsigned char nr, i;
601
602 p = Conn_get_private(C);
603 if (!p->pie1_init) {
604 const char *u =
605 "window.wsdemo.pie1_update = function(a) {\n"
606 " var i;\n"
607 " var angle, last_angle = 0, pcx, pcy;\n"
608 " // compute sum\n"
609 " var sum = 0;\n"
610 " for (i = 0; i < a.length; i++)\n"
611 " sum += a[i].value;\n"
612 ""
613 " var canvas = document.getElementById('pie1');\n"
614 " var ctx = canvas.getContext('2d');\n"
615 " ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n"
616 ""
617 " ctx.shadowColor = '#444';\n"
618 " ctx.shadowBlur = 3;\n"
619 " ctx.shadowOffsetX = 2;\n"
620 " ctx.shadowOffsetY = 2;\n"
621 " for (i = 0; i < a.length; i++) {\n"
622 " angle = a[i].value * 2 * Math.PI / sum;\n"
623 " ctx.fillStyle = a[i].color;\n"
624 " pcx = 4 * Math.cos((2 * last_angle + angle) / 2);\n"
625 " pcy = 4 * Math.sin((2 * last_angle + angle) / 2);\n"
626 " ctx.beginPath();\n"
627 " ctx.arc(50 + pcx, 50 + pcy, 40, last_angle + 0.03, last_angle + angle - 0.03);\n"
628 " ctx.lineTo(50 + pcx, 50 + pcy);\n"
629 " ctx.closePath();\n"
630 " ctx.fill();\n"
631 " ctx.strokeStyle = '#444';\n"
632 " ctx.stroke();\n"
633 ""
634 " last_angle += angle;\n"
635 " }\n"
636 "}";
637 push_code(C, u);
638 p->pie1_init = 1;
639 p->pie1_count = 4;
640 }
641
642 p->pie1_count++;
643 p->pie1_count %= 5;
644 if (p->pie1_count != 0)
645 return;
646
647 strcpy(vars, "[ "); add = "";
648 nr = 3 + random() % 3;
649 for (i = 0; i < nr; i++) {
650 char tmp[64];
651 unsigned int v;
652
653 v = 100 + (unsigned int) random() % 1000;
654 snprintf(tmp, sizeof(tmp), "%s{ name:\"%s\", value:%u, color:'#%06lx' }",
655 add, names[i], v, random() % 0x1000000);
656 strcat(vars, tmp);
657 add = ", ";
658 }
659 strcat(vars, "]");
660
661 snprintf(code, sizeof(code), "window.wsdemo.pie1_update(%s)", vars);
662 push_code(C, code);
344 663 } }
345 664
346 665 static void trigger(struct Conn *C) static void trigger(struct Conn *C)
347 666 { {
348 667 struct priv *p; struct priv *p;
349 double avg;
350 668
351 669 Log(0, "%llu %s from %s/%d\n", Conn_get_id(C), __func__, Log(0, "%llu %s from %s/%d\n", Conn_get_id(C), __func__,
352 670 Conn_addr_remote(C), Conn_port_remote(C)); Conn_addr_remote(C), Conn_port_remote(C));
 
... ... static void trigger(struct Conn *C)
354 672 p = Conn_get_private(C); p = Conn_get_private(C);
355 673 if (p->main_init == 0) { if (p->main_init == 0) {
356 674 // Here goes some init stuff // Here goes some init stuff
357 push_code(C, "window.wsdemo = [];\n"
675 const char *code =
676 "window.wsdemo = [];\n"
677 ""
678 "window.wsdemo.button = function(a) {\n"
679 " var data = {\n"
680 " op: 'button',\n"
681 " what: a\n"
682 " };\n"
683 " ws.send(JSON.stringify(data));\n"
684 "}\n"
685 ""
358 686 "window.wsdemo.my_resize = function(e) {\n" "window.wsdemo.my_resize = function(e) {\n"
359 687 " var data = {\n" " var data = {\n"
360 688 " op: 'resize',\n" " op: 'resize',\n"
 
... ... static void trigger(struct Conn *C)
364 692 " ws.send(JSON.stringify(data));\n" " ws.send(JSON.stringify(data));\n"
365 693 "}\n" "}\n"
366 694 "window.addEventListener('resize', window.wsdemo.my_resize, true);\n" "window.addEventListener('resize', window.wsdemo.my_resize, true);\n"
367 "window.wsdemo.my_resize();\n");
695 "window.wsdemo.my_resize();\n";
696 push_code(C, code);
697
698 p->per1_percent = random() % 50;
699 p->per2_percent = random() % 50;
700
368 701 p->main_init = 1; p->main_init = 1;
369 702 } }
370 703
371 /* This must be global, not per connection */
372 getloadavg(&avg, 1); avg *= 100;
373 load_current = (load_current + 1) % 100;
374 load[++load_current] = avg;
704 update_global();
375 705
376 706 // We wait for client to send the screen size // We wait for client to send the screen size
377 707 if (!p->x) if (!p->x)
378 708 return; return;
379 709
380 progress_bar1(C);
381 progress_bar2(C);
710 per1(C);
711 per2(C);
382 712 load1(C); load1(C);
383 713 band1(C); band1(C);
384 714 arc1(C); arc1(C);
715 bar1(C);
716 // canvas demos
717 cyl1(C);
718 pie1(C);
385 719 } }
386 720
387 721 static const char main_screen[] = static const char main_screen[] =
388 722 "<div class=\"gem\" width=\"120px\">\n" "<div class=\"gem\" width=\"120px\">\n"
389 723 "Progress bar 1 (div)\n" "Progress bar 1 (div)\n"
390 724 "<div style=\"margin: 3px; height: 10px; width: 100px; background-color: #eeeeee; border: 1px solid\">\n" "<div style=\"margin: 3px; height: 10px; width: 100px; background-color: #eeeeee; border: 1px solid\">\n"
391 " <div id=\"progress_bar1\" style=\"height: 10px; width: 0px; background-color: red\"></div>\n"
725 " <div id=\"per1\" style=\"height: 10px; width: 0px; background-color: red\"></div>\n"
392 726 "</div>\n" "</div>\n"
393 "</div>\n"
394 "\n"
727 "</div>\n\n"
728 ""
395 729 "<div class=\"gem\" width=\"120px\">\n" "<div class=\"gem\" width=\"120px\">\n"
396 "Progress bar 2 (div)\n"
397 "<div style=\"margin: 3px; height: 10px; width: 100px; background-color: #eeeeee; border: 1px solid\">\n"
398 " <div id=\"progress_bar2\" style=\"height: 10px; width: 0px; background-color: red\"></div>\n"
399 "</div>\n"
400 "</div>\n"
401 "\n"
730 "Progress bar 2 (svg)\n"
731 "<svg height=\"20\" width=\"110\" style=\"border: 1px solid black\">\n"
732 " <defs>\n"
733 " <linearGradient id=\"per2_gra1\" gradientTransform=\"rotate(90)\">\n"
734 " <stop offset=\"5%\" stop-color=\"#f60\" />\n"
735 " <stop offset=\"50%\" stop-color=\"#ff6\" />\n"
736 " <stop offset=\"95%\" stop-color=\"#f60\" />\n"
737 " </linearGradient>\n"
738 " </defs>\n"
739 " <rect id=\"per2\" x=\"5\" y=\"5\" width=\"0\" height=\"10\" fill=\"url(#per2_gra1)\"/>\n"
740 " <rect x=\"5\" y=\"5\" width=\"100\" height=\"10\" style=\"fill:transparent; stroke-width:.1; stroke:black\"/>\n"
741 "</svg>\n"
742 "</div>\n\n"
743 ""
402 744 "<div class=\"gem\" width=\"120px\">\n" "<div class=\"gem\" width=\"120px\">\n"
403 745 "Server load (SVG)\n" "Server load (SVG)\n"
404 746 "<svg id=\"load1_container\" height=\"102\" width=\"102\" style=\"border: 1px solid green\">\n" "<svg id=\"load1_container\" height=\"102\" width=\"102\" style=\"border: 1px solid green\">\n"
405 747 " <g id=\"load1\"></g>\n" " <g id=\"load1\"></g>\n"
406 748 " <text id=\"load1_text\" x=\"2\" y=\"99\" style=\"font-size: 10px\">Load here</text>\n" " <text id=\"load1_text\" x=\"2\" y=\"99\" style=\"font-size: 10px\">Load here</text>\n"
407 749 "</svg>\n" "</svg>\n"
408 "<span class=\"note\">Note: the width of the SVG is scaled based on available width.</span>\n"
409 "</div>\n"
410 "\n"
411 "<div class=\"gem\" width=\"420px\">\n"
750 "<div class=\"note\" width=\"100px\">Note: the width of the SVG is scaled based on"
751 " available width, but no more than 100px; previous values are pushed by the server.</div>\n"
752 "</div>\n\n"
753 ""
754 "<div class=\"gem\" TODOwidth=\"420px\">\n"
412 755 "Bandwidth (SVG)\n" "Bandwidth (SVG)\n"
413 756 "<svg id=\"band1_container\" height=\"102\" width=\"100\" style=\"border: 1px solid green\">\n" "<svg id=\"band1_container\" height=\"102\" width=\"100\" style=\"border: 1px solid green\">\n"
414 757 " <g id=\"band1\"></g>\n" " <g id=\"band1\"></g>\n"
 
... ... static const char main_screen[] =
416 759 " <text id=\"band1_text_up\" x=\"1\" y=\"7\" style=\"font-size: 5pt\"></text>\n" " <text id=\"band1_text_up\" x=\"1\" y=\"7\" style=\"font-size: 5pt\"></text>\n"
417 760 " <text id=\"band1_text_down\" x=\"1\" y=\"100\" style=\"font-size: 5pt\"></text>\n" " <text id=\"band1_text_down\" x=\"1\" y=\"100\" style=\"font-size: 5pt\"></text>\n"
418 761 "</svg>\n" "</svg>\n"
419 "<span class=\"note\">Note: the width of the SVG is scaled based on available width.</span>\n"
420 "</div>\n"
421 "\n"
762 "<div class=\"note\" width=\"200px\">Note: the width of the SVG is"
763 " scaled based on available width, but no more than 200px.</div>\n"
764 "</div>\n\n"
765 ""
422 766 "<div class=\"gem\" width=\"420px\">\n" "<div class=\"gem\" width=\"420px\">\n"
423 "Arc 1 (SVG)\n"
767 "Arc 1 (SVG arcs + div text)\n"
424 768 "<svg height=\"100\" width=\"100\" style=\"border: 1px solid green\">\n" "<svg height=\"100\" width=\"100\" style=\"border: 1px solid green\">\n"
425 769 "<defs>\n" "<defs>\n"
426 770 " <filter id=\"ds1\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n" " <filter id=\"ds1\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n"
 
... ... static const char main_screen[] =
429 773 "</defs>\n" "</defs>\n"
430 774 " <circle r=\"40\" cx=\"50\" cy=\"50\" fill=\"transparent\" stroke=\"black\" stroke-width=\"10\" filter=\"url(#ds1)\"/>\n" " <circle r=\"40\" cx=\"50\" cy=\"50\" fill=\"transparent\" stroke=\"black\" stroke-width=\"10\" filter=\"url(#ds1)\"/>\n"
431 775 " <g id=\"arc1\">\n" " <g id=\"arc1\">\n"
776 "" // a r1 r2 angle largeArcFlag sweepFlag dx dy
432 777 " <path d=\"M 10 50 a 40 40 0 0 1 0 0\" fill=\"transparent\" stroke=\"#f00\" stroke-width=\"10\"/>\n" " <path d=\"M 10 50 a 40 40 0 0 1 0 0\" fill=\"transparent\" stroke=\"#f00\" stroke-width=\"10\"/>\n"
433 778 " <path d=\"M 10 50 a 40 40 0 0 1 0 0\" fill=\"transparent\" stroke=\"#00f\" stroke-width=\"10\"\"/>\n" " <path d=\"M 10 50 a 40 40 0 0 1 0 0\" fill=\"transparent\" stroke=\"#00f\" stroke-width=\"10\"\"/>\n"
434 779 " <path d=\"M 10 50 a 40 40 0 0 1 0 0\" fill=\"transparent\" stroke=\"#f0f\" stroke-width=\"10\"\"/>\n" " <path d=\"M 10 50 a 40 40 0 0 1 0 0\" fill=\"transparent\" stroke=\"#f0f\" stroke-width=\"10\"\"/>\n"
 
... ... static const char main_screen[] =
443 788 " <text x=\"30\" y=\"72\" fill=\"#990\"></text>\n" " <text x=\"30\" y=\"72\" fill=\"#990\"></text>\n"
444 789 " </g>\n" " </g>\n"
445 790 "</svg>\n" "</svg>\n"
791 "</div>\n\n"
792 ""
793 "<div class=\"gem\" width=\"420px\">\n"
794 "Bar 1 (SVG lines + SVG text)\n"
795 "<svg height=\"100\" width=\"100\" style=\"border: 1px solid green\">\n"
796 " <line x1=\"0\" x2=\"100\" y1=\"85\" y2=\"85\" style=\"stroke: red\"/>\n"
797 " <g id=\"bar1\"></g>\n"
798 " <g id=\"bar1_text\"></g>\n"
799 " <g id=\"bar1_values\"></g>\n"
800 "</svg>\n"
801 "</div>\n\n"
802 ""
803 "<div class=\"gem\">\n"
804 "Cylinders (canvas, 2D)\n"
805 "<canvas id=\"cyl1\" width=\"100px\" height=\"100px\">\n"
806 " Your browser does not support canvas.\n"
807 "</canvas>\n"
808 "</div>\n"
809 ""
810 "<div class=\"gem\">\n"
811 "Pie (canvas, 2D)\n"
812 "<canvas id=\"pie1\" width=\"100px\" height=\"100px\">\n"
813 " Your browser does not support canvas.\n"
814 "</canvas>\n"
815 "</div>\n"
816 ""
817 "<div class=\"gem\">\n"
818 "Buttons\n"
819 "<input type=\"button\" onclick=\"window.wsdemo.button('notify');\""
820 " value=\"trigger notification\" />\n"
446 821 "</div>\n"; "</div>\n";
447 // A r1 r2 angle largeArcFlag sweepFlag x y
448 822
449 823 static void accept_cb(struct Conn *C) static void accept_cb(struct Conn *C)
450 824 { {
 
... ... static void process_json(struct Conn *C, struct json_object *j)
580 954 Log(10, "\tWe have a resize event [x=%u y=%u]!\n", Log(10, "\tWe have a resize event [x=%u y=%u]!\n",
581 955 priv->x, priv->y); priv->x, priv->y);
582 956
583 notify(C, "Screen resized to %u/%u", priv->x, priv->y);
957 return;
958 }
959
960 if (strcmp(s_op, "button") == 0) {
961 json_object_object_get_ex(j, "what", &text);
962 s_text = json_object_get_string(text);
963
964 if (strcmp(s_text, "notify") == 0) {
965 notify(C, "Welcome to wsdemo! You can push a notification from"
966 " the server whenever is needed.");
967 }
584 968 return; return;
585 969 } }
586 970
File examples/wsdemo.data/main.css changed (mode: 100644) (index 3492b8f..a930e99)
... ... body {
8 8
9 9 #welcome { #welcome {
10 10 border: 1px solid black; border: 1px solid black;
11 padding: 5px;
11 padding: 3px;
12 12 margin: 2px; margin: 2px;
13 13
14 14 flex: 1 100%; flex: 1 100%;
 
... ... body {
16 16
17 17 #my_status { #my_status {
18 18 border: 1px solid black; border: 1px solid black;
19 padding: 5px;
19 padding: 3px;
20 20 margin: 2px; margin: 2px;
21 21
22 22 flex: 1 100%; flex: 1 100%;
 
... ... body {
37 37 } }
38 38
39 39 .gem { .gem {
40 padding: 5px;
40 padding: 3px;
41 41 border: 1px solid blue; border: 1px solid blue;
42 x-width: 150px;
43 margin: 5px;
42 margin: 3px;
44 43
45 44 display: flex; display: flex;
46 45 flex-direction: column; flex-direction: column;
File examples/wsdemo.data/main.js changed (mode: 100644) (index 42d6cfa..9b2a23d)
... ... function reconnect()
91 91 if (j.op == 'ka') { if (j.op == 'ka') {
92 92 //console.log('got a ka answer from server'); //console.log('got a ka answer from server');
93 93 } else if (j.op == 'init') { } else if (j.op == 'init') {
94 //console.log('got answer to init command');
95 div_status.innerHTML = 'Status: OK (id ' + j.id + ')';
94 var date = new Date();
95 div_status.innerHTML = 'Status: OK (id ' + j.id +
96 '; ' + date.toString() + ')';
96 97 div_big.innerHTML = j.html; div_big.innerHTML = j.html;
97 98 } else if (j.op == 'push') { } else if (j.op == 'push') {
98 99 if (j.obj == 'exec') { if (j.obj == 'exec') {
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/catalinux/Conn

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/catalinux/Conn

Clone this repository using git:
git clone git://git.rocketgit.com/user/catalinux/Conn

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main