iosignal 3.0.1 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/{docs/README.ko.md → README.ko.md} +204 -9
  2. package/README.md +424 -8
  3. package/dist/io.js +1 -1
  4. package/dist/io.js.map +1 -1
  5. package/dist/io.min.js +1 -1
  6. package/dist/io.min.js.map +1 -1
  7. package/dist/iosignal.js +131 -29
  8. package/examples/react-chat-js/package-lock.json +311 -216
  9. package/examples/react-chat-js/package.json +6 -6
  10. package/examples/react-chat-js/src/App.jsx +4 -4
  11. package/examples/server/package-lock.json +47 -0
  12. package/examples/svelte-chat-js/.devtools +3 -0
  13. package/examples/svelte-chat-js/README.md +38 -0
  14. package/examples/svelte-chat-js/package-lock.json +1505 -0
  15. package/examples/svelte-chat-js/package.json +22 -0
  16. package/examples/svelte-chat-js/src/app.css +105 -0
  17. package/examples/svelte-chat-js/src/app.d.ts +13 -0
  18. package/examples/svelte-chat-js/src/app.html +12 -0
  19. package/examples/svelte-chat-js/src/lib/images/github.svg +1 -0
  20. package/examples/svelte-chat-js/src/lib/images/svelte-logo.svg +1 -0
  21. package/examples/svelte-chat-js/src/lib/images/svelte-welcome.png +0 -0
  22. package/examples/svelte-chat-js/src/lib/images/svelte-welcome.webp +0 -0
  23. package/examples/svelte-chat-js/src/lib/shared_io.js +12 -0
  24. package/examples/svelte-chat-js/src/routes/+layout.svelte +9 -0
  25. package/examples/svelte-chat-js/src/routes/+page.js +3 -0
  26. package/examples/svelte-chat-js/src/routes/+page.svelte +162 -0
  27. package/examples/svelte-chat-js/static/favicon.svg +1 -0
  28. package/examples/svelte-chat-js/static/global.css +19 -0
  29. package/examples/svelte-chat-js/static/robots.txt +3 -0
  30. package/examples/svelte-chat-js/svelte.config.js +15 -0
  31. package/examples/svelte-chat-js/vite.config.js +6 -0
  32. package/index.js +2 -1
  33. package/package.json +1 -1
  34. package/src/client/IOCore.js +18 -5
  35. package/src/client/browser/IOWebSocket.js +1 -16
  36. package/src/server/Manager.js +16 -0
  37. package/src/server/Remote.js +5 -0
  38. package/src/server/Server.js +85 -21
  39. package/src/server/serverOption.js +2 -2
  40. package/test-nodejs/client-playToggle.js +19 -0
@@ -1,4 +1,4 @@
1
- [ [English](../README.md) | 한국어 ]
1
+ [ [English](README.md) | 한국어 ]
2
2
 
3
3
 
4
4
  # IOSignal
@@ -11,7 +11,21 @@ IOSignal은 웹 브라우저, Node.js, 아두이노 간의 실시간 통신을
11
11
  $ npm i iosignal
12
12
  ```
13
13
 
14
- ## IOSignal 클라이언트
14
+ ## 예제
15
+
16
+ 이 프로젝트는 다양한 환경에서 `iosignal`을 사용하는 방법을 보여주는 여러 예제를 `examples` 디렉토리에 포함하고 있습니다.
17
+
18
+ ### Node.js 서버 예제
19
+
20
+ `examples/server`에서 간단한 시그널링 서버를 사용할 수 있습니다. 이 서버는 클라이언트 예제들이 서로 통신하는 데 필요합니다.
21
+
22
+ **서버 실행 방법:**
23
+ ```shell
24
+ cd examples/server
25
+ npm install
26
+ node .
27
+ ```
28
+ 서버는 WebSocket 연결을 위해 `localhost:7777`에서 시작됩니다.
15
29
 
16
30
  ### React 클라이언트 예제
17
31
 
@@ -24,12 +38,7 @@ $ npm i iosignal
24
38
 
25
39
  **예제 실행 방법:**
26
40
 
27
- 1. 서버 디렉토리로 이동하여 서버를 시작합니다:
28
- ```shell
29
- cd examples/server
30
- npm install
31
- node .
32
- ```
41
+ 1. 예제 서버가 실행 중인지 확인하세요 (위의 설명 참조).
33
42
  2. 새 터미널에서 React 프로젝트 디렉토리로 이동하여 종속성을 설치하고 개발 서버를 시작합니다:
34
43
  ```shell
35
44
  cd examples/react-chat-js
@@ -153,6 +162,192 @@ function App() {
153
162
  export default App;
154
163
  ```
155
164
 
165
+ ### Svelte 클라이언트 예제
166
+
167
+ `examples/svelte-chat-js`에서 샘플 Svelte 프로젝트를 확인할 수 있습니다. 이 예제는 실시간 채팅 기능을 위해 Svelte 5와 Runes를 사용하는 애플리케이션에 `iosignal`을 통합하는 방법을 보여줍니다.
168
+
169
+ **주요 개념:**
170
+
171
+ - **`$state`**: 메시지, 입력 필드, 연결 상태 등을 위한 반응형 상태 변수를 생성합니다.
172
+ - **`$effect`**: `io` 인스턴스의 생명주기를 관리합니다. 컴포넌트가 마운트될 때 실행되고, 반환된 정리(cleanup) 함수(`io.destroy()`를 호출하는)는 컴포넌트가 언마운트될 때 실행됩니다.
173
+
174
+ **예제 실행 방법:**
175
+
176
+ 1. 예제 서버가 실행 중인지 확인하세요 (위의 설명 참조).
177
+ 2. 새 터미널에서 Svelte 프로젝트 디렉토리로 이동하여 종속성을 설치하고 개발 서버를 시작합니다:
178
+ ```shell
179
+ cd examples/svelte-chat-js
180
+ npm install
181
+ npm run dev
182
+ ```
183
+
184
+ **예제 코드 (`+page.svelte`):**
185
+
186
+ ```svelte
187
+ <script>
188
+ import { dev, browser } from "$app/environment";
189
+ import IO from "iosignal/io.js";
190
+
191
+ // const url = 'ws://192.168.0.15:7777';
192
+ const url = "ws://localhost:7777";
193
+ const channel_tag = "channel#topic";
194
+
195
+ let messages = $state([]);
196
+ let input = $state("Hello, World!");
197
+ let ioState = $state(null);
198
+ let cid = $state(null);
199
+ let counts = $state({ instances: 0, websockets: 0 });
200
+ let io = null;
201
+ let messagesEnd;
202
+
203
+ const scrollToBottom = () => {
204
+ messagesEnd?.scrollIntoView({ behavior: "smooth" });
205
+ };
206
+
207
+ if (browser) {
208
+ io = new IO(url);
209
+ if (dev)
210
+ console.log("new io:", IO.version, IO.instanceCount, IO.webSocketCount);
211
+
212
+ counts = { instances: IO.instanceCount, websockets: IO.webSocketCount };
213
+
214
+ const handleReady = () => {
215
+ console.log("ready cid:", io.cid);
216
+ cid = io.cid;
217
+ io.subscribe(channel_tag);
218
+ };
219
+
220
+ const handleChange = (state) => {
221
+ ioState = state;
222
+ counts = { instances: IO.instanceCount, websockets: IO.webSocketCount };
223
+ };
224
+
225
+ const handleChannelMessage = (msgObj, tag) => {
226
+ console.log("Received message in App:", msgObj, tag);
227
+ messages = [...messages, `${msgObj.cid} : ${msgObj.text}`];
228
+ scrollToBottom();
229
+ };
230
+
231
+ const handleError = (error) => {
232
+ console.error("IO Error in App:", error);
233
+ ioState = `Error: ${error.message}`;
234
+ };
235
+
236
+ io.on("ready", handleReady);
237
+ io.on("change", handleChange);
238
+ io.on(channel_tag, handleChannelMessage);
239
+ io.on("error", handleError);
240
+
241
+ $effect(() => {
242
+ return () => {
243
+ io.destroy();
244
+ io = null;
245
+ };
246
+ });
247
+ }
248
+
249
+ const sendMessage = () => {
250
+ if (input.trim()) {
251
+ // console.log('Sending message:', input);
252
+ const msgObj = { text: input, cid: io.cid };
253
+ // console.log('Sending message object:', msgObj);
254
+ io.signal(channel_tag, msgObj);
255
+ input = "date" + Date.now();
256
+ }
257
+ };
258
+
259
+ let ioStateStyle = $derived(
260
+ `color: ${ioState === "ready" ? "green" : "red"}; font-weight: bold;`,
261
+ );
262
+ </script>
263
+
264
+ <div class="App">
265
+ <h1>Svelte 5 Chat Example</h1>
266
+ <div>URL: {url}</div>
267
+ <div>Channel: {channel_tag}</div>
268
+ <div>IO State: <span style={ioStateStyle}>{ioState}</span></div>
269
+ <div>Client ID: {cid}</div>
270
+ <div>IO Instances: {counts.instances}</div>
271
+ <div>WebSockets Created: {counts.websockets}</div>
272
+ <div class="messages">
273
+ {#each messages as msg, index (index)}
274
+ <div>{msg}</div>
275
+ {/each}
276
+ <div bind:this={messagesEnd}></div>
277
+ </div>
278
+ <div class="input-area">
279
+ <input
280
+ type="text"
281
+ bind:value={input}
282
+ onkeyup={(e) => e.key === "Enter" && sendMessage()}
283
+ disabled={ioState !== "ready"}
284
+ />
285
+ <button onclick={sendMessage} disabled={ioState !== "ready"}> Send </button>
286
+ </div>
287
+ </div>
288
+
289
+ <style>
290
+ .App {
291
+ height: 100%;
292
+ margin: 0;
293
+ display: flex;
294
+ flex-direction: column;
295
+ padding: 20px;
296
+ box-sizing: border-box;
297
+ }
298
+
299
+ h1 {
300
+ margin-top: 0;
301
+ color: #333;
302
+ }
303
+
304
+ .messages {
305
+ flex-grow: 1;
306
+ border: 1px solid #ccc;
307
+ padding: 10px;
308
+ overflow-y: auto;
309
+ margin-bottom: 10px;
310
+ display: flex;
311
+ flex-direction: column;
312
+ justify-content: flex-end;
313
+ }
314
+
315
+ .messages div {
316
+ background-color: #f0f0f0;
317
+ padding: 8px;
318
+ margin-bottom: 5px;
319
+ border-radius: 5px;
320
+ text-align: left;
321
+ }
322
+
323
+ .input-area {
324
+ display: flex;
325
+ gap: 10px;
326
+ margin-top: auto;
327
+ }
328
+
329
+ .input-area input {
330
+ flex-grow: 1;
331
+ padding: 10px;
332
+ border: 1px solid #ccc;
333
+ border-radius: 5px;
334
+ }
335
+
336
+ .input-area button {
337
+ padding: 10px 15px;
338
+ background-color: #007bff;
339
+ color: white;
340
+ border: none;
341
+ border-radius: 5px;
342
+ cursor: pointer;
343
+ }
344
+
345
+ .input-area button:hover {
346
+ background-color: #0056b3;
347
+ }
348
+ </style>
349
+ ```
350
+
156
351
  ### 브라우저 클라이언트 : ESM
157
352
 
158
353
  - 로컬 파일: "dist/io.js"
@@ -341,7 +536,7 @@ Fri, 09 Feb 2024 14:24:37 GMT
341
536
  - 아두이노는 CongSocket을 사용합니다.
342
537
 
343
538
  ## IOSignal 서버 아키텍처
344
- ![IOSignal](../iosignal_architecture.png)
539
+ ![IOSignal](./docs/iosignal_architecture.png)
345
540
 
346
541
  ## IOSignal 저장소
347
542
 
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [ English | [한국어](docs/README.ko.md) ]
1
+ [ English | [한국어](README.ko.md) ]
2
2
 
3
3
  # IOSignal
4
4
 
@@ -10,9 +10,21 @@ IOSignal enables real-time communication across web browsers, Node.js, and Ardui
10
10
  $ npm i iosignal
11
11
  ```
12
12
 
13
+ ## Examples
13
14
 
15
+ This project includes several examples in the `examples` directory to demonstrate how to use `iosignal` in different environments.
14
16
 
15
- ## IOSignal Client
17
+ ### Node.js Server Example
18
+
19
+ A simple signaling server is available in `examples/server`. This server is required for the client examples to communicate with each other.
20
+
21
+ **To run the server:**
22
+ ```shell
23
+ cd examples/server
24
+ npm install
25
+ node .
26
+ ```
27
+ The server will start on `localhost:7777` for WebSocket connections.
16
28
 
17
29
 
18
30
  ### React Client Example
@@ -27,12 +39,7 @@ A sample React project is available in `examples/react-chat-js`. This example de
27
39
 
28
40
  **To run the example:**
29
41
 
30
- 1. Navigate to the server directory and start the server:
31
- ```shell
32
- cd examples/server
33
- npm install
34
- node .
35
- ```
42
+ 1. Make sure the example server is running.
36
43
  2. In a new terminal, navigate to the React project directory, install dependencies, and start the development server:
37
44
  ```shell
38
45
  cd examples/react-chat-js
@@ -156,6 +163,415 @@ function App() {
156
163
  export default App;
157
164
  ```
158
165
 
166
+ ### Svelte Client Example
167
+
168
+ A sample Svelte project is available in `examples/svelte-chat-js`. This example shows how to use `iosignal` in a Svelte 5 application with Runes for real-time chat.
169
+
170
+ **Key Concepts:**
171
+
172
+ - **`$state`**: To create reactive state variables for messages, input fields, and connection status.
173
+ - **`$effect`**: To manage the lifecycle of the `io` instance. It runs when the component mounts, and the returned cleanup function (which calls `io.destroy()`) runs when the component unmounts.
174
+
175
+ **To run the example:**
176
+
177
+ 1. Make sure the example server is running (see instructions above).
178
+ 2. In a new terminal, navigate to the Svelte project directory, install dependencies, and start the development server:
179
+ ```shell
180
+ cd examples/svelte-chat-js
181
+ npm install
182
+ npm run dev
183
+ ```
184
+
185
+ **Example Code (`+page.svelte`):**
186
+
187
+ ```svelte
188
+ <script>
189
+ import { dev, browser } from "$app/environment";
190
+ import IO from "iosignal/io.js";
191
+
192
+ // const url = 'ws://192.168.0.15:7777';
193
+ const url = "ws://localhost:7777";
194
+ const channel_tag = "channel#topic";
195
+
196
+ let messages = $state([]);
197
+ let input = $state("Hello, World!");
198
+ let ioState = $state(null);
199
+ let cid = $state(null);
200
+ let counts = $state({ instances: 0, websockets: 0 });
201
+ let io = null;
202
+ let messagesEnd;
203
+
204
+ const scrollToBottom = () => {
205
+ messagesEnd?.scrollIntoView({ behavior: "smooth" });
206
+ };
207
+
208
+ if (browser) {
209
+ io = new IO(url);
210
+ if (dev)
211
+ console.log("new io:", IO.version, IO.instanceCount, IO.webSocketCount);
212
+
213
+ counts = { instances: IO.instanceCount, websockets: IO.webSocketCount };
214
+
215
+ const handleReady = () => {
216
+ console.log("ready cid:", io.cid);
217
+ cid = io.cid;
218
+ io.subscribe(channel_tag);
219
+ };
220
+
221
+ const handleChange = (state) => {
222
+ ioState = state;
223
+ counts = { instances: IO.instanceCount, websockets: IO.webSocketCount };
224
+ };
225
+
226
+ const handleChannelMessage = (msgObj, tag) => {
227
+ console.log("Received message in App:", msgObj, tag);
228
+ messages = [...messages, `${msgObj.cid} : ${msgObj.text}`];
229
+ scrollToBottom();
230
+ };
231
+
232
+ const handleError = (error) => {
233
+ console.error("IO Error in App:", error);
234
+ ioState = `Error: ${error.message}`;
235
+ };
236
+
237
+ io.on("ready", handleReady);
238
+ io.on("change", handleChange);
239
+ io.on(channel_tag, handleChannelMessage);
240
+ io.on("error", handleError);
241
+
242
+ $effect(() => {
243
+ return () => {
244
+ io.destroy();
245
+ io = null;
246
+ };
247
+ });
248
+ }
249
+
250
+ const sendMessage = () => {
251
+ if (input.trim()) {
252
+ // console.log('Sending message:', input);
253
+ const msgObj = { text: input, cid: io.cid };
254
+ // console.log('Sending message object:', msgObj);
255
+ io.signal(channel_tag, msgObj);
256
+ input = "date" + Date.now();
257
+ }
258
+ };
259
+
260
+ let ioStateStyle = $derived(
261
+ `color: ${ioState === "ready" ? "green" : "red"}; font-weight: bold;`,
262
+ );
263
+ </script>
264
+
265
+ <div class="App">
266
+ <h1>Svelte 5 Chat Example</h1>
267
+ <div>URL: {url}</div>
268
+ <div>Channel: {channel_tag}</div>
269
+ <div>IO State: <span style={ioStateStyle}>{ioState}</span></div>
270
+ <div>Client ID: {cid}</div>
271
+ <div>IO Instances: {counts.instances}</div>
272
+ <div>WebSockets Created: {counts.websockets}</div>
273
+ <div class="messages">
274
+ {#each messages as msg, index (index)}
275
+ <div>{msg}</div>
276
+ {/each}
277
+ <div bind:this={messagesEnd}></div>
278
+ </div>
279
+ <div class="input-area">
280
+ <input
281
+ type="text"
282
+ bind:value={input}
283
+ onkeyup={(e) => e.key === "Enter" && sendMessage()}
284
+ disabled={ioState !== "ready"}
285
+ />
286
+ <button onclick={sendMessage} disabled={ioState !== "ready"}> Send </button>
287
+ </div>
288
+ </div>
289
+
290
+ <style>
291
+ .App {
292
+ height: 100%;
293
+ margin: 0;
294
+ display: flex;
295
+ flex-direction: column;
296
+ padding: 20px;
297
+ box-sizing: border-box;
298
+ }
299
+
300
+ h1 {
301
+ margin-top: 0;
302
+ color: #333;
303
+ }
304
+
305
+ .messages {
306
+ flex-grow: 1;
307
+ border: 1px solid #ccc;
308
+ padding: 10px;
309
+ overflow-y: auto;
310
+ margin-bottom: 10px;
311
+ display: flex;
312
+ flex-direction: column;
313
+ justify-content: flex-end;
314
+ }
315
+
316
+ .messages div {
317
+ background-color: #f0f0f0;
318
+ padding: 8px;
319
+ margin-bottom: 5px;
320
+ border-radius: 5px;
321
+ text-align: left;
322
+ }
323
+
324
+ .input-area {
325
+ display: flex;
326
+ gap: 10px;
327
+ margin-top: auto;
328
+ }
329
+
330
+ .input-area input {
331
+ flex-grow: 1;
332
+ padding: 10px;
333
+ border: 1px solid #ccc;
334
+ border-radius: 5px;
335
+ }
336
+
337
+ .input-area button {
338
+ padding: 10px 15px;
339
+ background-color: #007bff;
340
+ color: white;
341
+ border: none;
342
+ border-radius: 5px;
343
+ cursor: pointer;
344
+ }
345
+
346
+ .input-area button:hover {
347
+ background-color: #0056b3;
348
+ }
349
+ </style>
350
+ ```
351
+
352
+ ### Browser client : ESM
353
+
354
+ - local file: "dist/io.js"
355
+ - CDN: https://cdn.jsdelivr.net/npm/iosignal/dist/io.js
356
+
357
+ ```html
358
+ <html>
359
+
360
+ <script type="module">
361
+ import IO from "../dist/io.js"
362
+
363
+ const io = new IO('wss://io.iosignal.net/ws')
364
+ io.listen('channel#topic', (...args)={
365
+ console.log( args )
366
+ })
367
+
368
+ io.on('ready',()=>{
369
+ console.log('ready cid:', io.cid )
370
+ })
371
+
372
+ </script>
373
+
374
+ </html>
375
+ ```
376
+
377
+
378
+ ### Browser Client : UMD(IIFE)
379
+ - local file: "dist/io.min.js"
380
+ - CDN: https://cdn.jsdelivr.net/npm/iosignal/dist/io.min.js
381
+
382
+ ```html
383
+ <html>
384
+ <script src="../dist/io.min.js"></script>
385
+ <script>
386
+ console.log('IO', IO) // default global variable name is IO
387
+
388
+ var io1 = new IO('ws://localhost:7777')
389
+ var io2 = new IO('ws://localhost:7777')
390
+ var io3 = new IO('ws://localhost:7777')
391
+
392
+ io1.on('error', errorHandler )
393
+ io2.on('error', errorHandler )
394
+ io3.on('error', errorHandler )
395
+
396
+ let channelName = 'io'
397
+
398
+ // classic style subsribing
399
+ io1.on('ready',e=>{
400
+ io1.subscribe(channelName)
401
+ io1.on(channelName, (...args)=>{
402
+ // console.log('io1 received', args )
403
+ let msg = '[io1] ' + JSON.stringify( args )
404
+ addMessage(msg)
405
+ })
406
+ })
407
+
408
+ // iosignal style subscribing
409
+ io2.listen(channelName, (...args)=>{
410
+ // console.log('io2 receive', args )
411
+ let msg = '[io2] ' + JSON.stringify( args )
412
+ addMessage(msg)
413
+ })
414
+
415
+ setInterval(e=>{
416
+ io3.signal(channelName, 'single string') // single string payload
417
+ io3.signal(channelName, Date.now(), 'a', 2 , {key: 3} ) //multiple payload
418
+ io3.signal(channelName ) // pure signal without payload.
419
+ },3000)
420
+
421
+ function addMessage(msg){
422
+ // ...
423
+ }
424
+
425
+ function errorHandler(e){
426
+ // ...
427
+ }
428
+ </script>
429
+
430
+ </html>
431
+ ```
432
+
433
+
434
+
435
+
436
+ ### NodeJS Client
437
+ ```js
438
+ import { IO } from "iosignal"
439
+
440
+ const io = new IO('wss://io.iosignal.net/ws')
441
+
442
+ io.on('ready', ()=>{
443
+ console.log('ready cid:', io.cid)
444
+ io.signal('#screen','playToggle')
445
+ });
446
+
447
+ io.listen('#notify', (...args)=>{
448
+ console.log( args )
449
+ })
450
+
451
+ io.on('error',err=>{
452
+ console.log('err', err)
453
+ })
454
+
455
+ ```
456
+
457
+
458
+
459
+
460
+ ## IOSignal Server
461
+
462
+
463
+ ```js
464
+ import { Server } from "iosignal"
465
+
466
+ const server = new Server(
467
+ {
468
+ port: 7777,
469
+ congPort: 8888,
470
+ showMetric: 2,
471
+ showMessage: 'message' // show signal message
472
+ })
473
+
474
+ ```
475
+
476
+ - port: <Number> IOSignal over WebSocket
477
+ - congPort: <Number> IOsignal over CongSocket
478
+ - showMetric: 1|2|3 show clients cid(state) info
479
+ - showMessage: "none"|"message" show signal buffer message
480
+ - timeout <milliseconds> ping period & timeout (min. 1000)
481
+
482
+ ### IOSignal API
483
+
484
+ IOSignal API examples
485
+ - src/api_reply.js // 'echo', 'date', 'unixtime'
486
+ - src/api_sudo.js // server admin monitoring command
487
+ - src/RedisAPI.js // redis command and response service
488
+
489
+
490
+ To register an API service with the server, use the api() method
491
+
492
+ `api('api_name', module )`
493
+
494
+ ```js
495
+ // node.js
496
+ import { Server ,api_reply } from 'iosignal'
497
+ const server = new Server( { port: 7777 } )
498
+ server.api('reply', api_reply) // attach api module
499
+ ```
500
+
501
+ Example of a client calling the reply API
502
+
503
+ ```js
504
+ // web browser api client example
505
+ <script src="../dist/io.min.js"></script>
506
+ <script>
507
+ const io = new IO('ws://localhost:7777')
508
+
509
+ io.on('ready', async ()=>{
510
+ let res_echo = await io.req('reply', 'echo', 'hello' )
511
+ let res_date = await io.req('reply', 'date' )
512
+ let res_unixtime = await io.req('reply', 'unixtime' )
513
+
514
+ if( res_echo.ok ) console.log( res_echo.body )
515
+ if( res_date.ok ) console.log( res_date.body )
516
+ if( res_unixtime.ok ) console.log( res_unixtime.body )
517
+ });
518
+ </script>
519
+
520
+ // result
521
+ [ 'hello' ]
522
+ Fri, 09 Feb 2024 14:24:37 GMT
523
+ 1707488677
524
+
525
+ ```
526
+
527
+
528
+ ## Features
529
+
530
+ ### Built-in Message Trasport Protocol
531
+ - pub/sub multicast by channel name.
532
+ - uni-cast: one to one messaging by CID.
533
+ - `CID` is a Communication Id
534
+ - CID subscribing: subscribe one peer using CID.
535
+ - HomeChannel: group by IP address.
536
+
537
+ ### Built-in Security
538
+ - Authentication
539
+ - Encryption
540
+ - E2EE
541
+ - thanks to the `Boho` [ [github](https://github.com/remocons/boho) ]
542
+
543
+ ## Connection
544
+ - Web browser use WebSocket.
545
+ - Node.js use WebSocket or CongSocket.
546
+ - Arduino use CongSocket.
547
+
548
+ ## IOSignal Server Architecture
549
+ ![IOSignal](./docs/iosignal_architecture.png)
550
+
551
+ ## IOSignal repositories.
552
+
553
+ - Javascript: `iosignal` [ [github](https://github.com/remocons/iosignal) | [npm](https://www.npmjs.com/package/iosignal) ]
554
+ - Node.js server ( WebSocket, CongSocket)
555
+ - Node.js client ( WebSocket, CongSocket)
556
+ - Web Browser client( WebSocket)
557
+
558
+ - CLI program
559
+ - `iosignal-cli` [ [github](https://github.com/remocons/iosignal-cli) | [npm](https://www.npmjs.com/package/iosignal-cli) ]
560
+ - install: `npm i -g iosignal-cli` or `sudo npm i -g iosignal-cli`
561
+ - support mac, linux and windows.
562
+ - server and client
563
+
564
+ - Arduino iosignal library and examples:
565
+ - use Arduino Library Manager: `iosignal`
566
+ - or `iosignal-arduino` [ [github](https://github.com/remocons/iosignal-arduino) ]
567
+ - web app : http://test.iosignal.net
568
+
569
+ - Arduino remocon library and examples:
570
+ - use Arduino Library Manager: `remocon`
571
+ - or `remocon-arduino` [ [github](https://github.com/remocons/remocon-arduino) ]
572
+ - web app : https://remocon.kr
573
+
574
+
159
575
 
160
576
  ### Browser client : ESM
161
577