iosignal 3.0.0 → 3.1.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.
- package/README.ko.md +566 -0
- package/README.md +561 -2
- package/dist/io.d.ts +481 -0
- package/dist/io.js +3 -3
- package/dist/io.js.map +1 -1
- package/dist/io.min.js +3 -3
- package/dist/io.min.js.map +1 -1
- package/dist/iosignal.js +558 -104
- package/dist/types/client/IOCore.d.ts +408 -0
- package/dist/types/client/browser/IOWebSocket.d.ts +75 -0
- package/dist/types/common/constants.d.ts +169 -0
- package/dist/types/common/payload.d.ts +6 -0
- package/dist/types/common/quotaTable.d.ts +47 -0
- package/examples/react-chat-js/dist/assets/index-Cy4qaVcJ.js +56 -0
- package/examples/react-chat-js/dist/assets/index-NETrjYhz.css +1 -0
- package/examples/react-chat-js/dist/index.html +14 -0
- package/examples/react-chat-js/index.html +13 -0
- package/examples/react-chat-js/package-lock.json +1723 -0
- package/examples/react-chat-js/package.json +20 -0
- package/examples/react-chat-js/src/App.css +61 -0
- package/examples/react-chat-js/src/App.jsx +125 -0
- package/examples/react-chat-js/src/index.css +13 -0
- package/examples/react-chat-js/src/main.jsx +13 -0
- package/examples/react-chat-js/src/shared_io.js +12 -0
- package/examples/react-chat-js/vite.config.js +7 -0
- package/examples/server/index.js +12 -0
- package/examples/server/package-lock.json +47 -0
- package/examples/server/package.json +12 -0
- package/examples/svelte-chat-js/.devtools +3 -0
- package/examples/svelte-chat-js/README.md +38 -0
- package/examples/svelte-chat-js/package-lock.json +1505 -0
- package/examples/svelte-chat-js/package.json +22 -0
- package/examples/svelte-chat-js/src/app.css +105 -0
- package/examples/svelte-chat-js/src/app.d.ts +13 -0
- package/examples/svelte-chat-js/src/app.html +12 -0
- package/examples/svelte-chat-js/src/lib/images/github.svg +1 -0
- package/examples/svelte-chat-js/src/lib/images/svelte-logo.svg +1 -0
- package/examples/svelte-chat-js/src/lib/images/svelte-welcome.png +0 -0
- package/examples/svelte-chat-js/src/lib/images/svelte-welcome.webp +0 -0
- package/examples/svelte-chat-js/src/lib/shared_io.js +12 -0
- package/examples/svelte-chat-js/src/routes/+layout.svelte +9 -0
- package/examples/svelte-chat-js/src/routes/+page.js +3 -0
- package/examples/svelte-chat-js/src/routes/+page.svelte +162 -0
- package/examples/svelte-chat-js/static/favicon.svg +1 -0
- package/examples/svelte-chat-js/static/global.css +19 -0
- package/examples/svelte-chat-js/static/robots.txt +3 -0
- package/examples/svelte-chat-js/svelte.config.js +15 -0
- package/examples/svelte-chat-js/vite.config.js +6 -0
- package/package.json +9 -3
- package/rollup.config.js +11 -4
- package/src/client/IOCongSocket.js +20 -9
- package/src/client/IOCore.js +437 -79
- package/src/client/IOWS.js +12 -15
- package/src/client/browser/IOWebSocket.js +101 -17
- package/src/common/constants.js +91 -1
- package/tsconfig.json +24 -0
- package/docs/README.kr.md +0 -230
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[
|
|
1
|
+
[ English | [한국어](README.ko.md) ]
|
|
2
2
|
|
|
3
3
|
# IOSignal
|
|
4
4
|
|
|
@@ -10,9 +10,568 @@ 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.
|
|
16
|
+
|
|
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.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### React Client Example
|
|
31
|
+
|
|
32
|
+
A sample React project is available in `examples/react-chat-js`. This example demonstrates how to integrate `iosignal` into a React application for real-time chat functionality.
|
|
33
|
+
|
|
34
|
+
**Key Concepts:**
|
|
35
|
+
|
|
36
|
+
- **`useRef`**: To maintain a stable reference to the `io` instance across component re-renders.
|
|
37
|
+
- **`useEffect`**: To manage the lifecycle of the `io` instance, including initialization and cleanup. Event handlers are set up within this hook.
|
|
38
|
+
- To release the `io` instance when the component unmounts, use `io.destroy()`. Event handlers registered during mount are also automatically removed.
|
|
39
|
+
|
|
40
|
+
**To run the example:**
|
|
41
|
+
|
|
42
|
+
1. Make sure the example server is running.
|
|
43
|
+
2. In a new terminal, navigate to the React project directory, install dependencies, and start the development server:
|
|
44
|
+
```shell
|
|
45
|
+
cd examples/react-chat-js
|
|
46
|
+
npm install
|
|
47
|
+
npm run dev
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Example Code (`App.jsx`):**
|
|
51
|
+
|
|
52
|
+
If you open multiple browsers and enter a message, it will be delivered to each other via the server.
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
import { useState, useEffect, useRef } from 'react';
|
|
56
|
+
import './App.css';
|
|
57
|
+
import IO from 'iosignal/io.js';
|
|
58
|
+
|
|
59
|
+
const url = 'ws://localhost:7777';
|
|
60
|
+
const channel_tag = 'channel#topic';
|
|
61
|
+
|
|
62
|
+
function App() {
|
|
63
|
+
const [messages, setMessages] = useState([]);
|
|
64
|
+
const [input, setInput] = useState('Hello, World!');
|
|
65
|
+
const [ioState, setIoState] = useState(null);
|
|
66
|
+
const [cid, setCid] = useState(null);
|
|
67
|
+
const [counts, setCounts] = useState({ instances: 0, websockets: 0 });
|
|
68
|
+
const ioRef = useRef(null);
|
|
69
|
+
const messagesEndRef = useRef(null);
|
|
70
|
+
|
|
71
|
+
const scrollToBottom = () => {
|
|
72
|
+
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
scrollToBottom();
|
|
77
|
+
}, [messages]);
|
|
78
|
+
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
ioRef.current = new IO(url);
|
|
81
|
+
setCounts({ instances: IO.instanceCount, websockets: IO.webSocketCount });
|
|
82
|
+
|
|
83
|
+
const handleReady = () => {
|
|
84
|
+
console.log('ready cid:', ioRef.current.cid);
|
|
85
|
+
setCid(ioRef.current.cid);
|
|
86
|
+
ioRef.current.subscribe(channel_tag);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const handleChange = (state) => {
|
|
90
|
+
setIoState(state);
|
|
91
|
+
setCounts({ instances: IO.instanceCount, websockets: IO.webSocketCount });
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const handleChannelMessage = (msgObj, tag) => {
|
|
95
|
+
console.log('Received message in App:', msgObj, tag);
|
|
96
|
+
if (typeof msgObj === 'string') {
|
|
97
|
+
msgObj = { text: msgObj, cid: 'cli unknown' };
|
|
98
|
+
}
|
|
99
|
+
setMessages((prevMessages) => [...prevMessages, `${msgObj.cid} : ${msgObj.text}`]);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const handleError = (error) => {
|
|
103
|
+
console.error('IO Error in App:', error);
|
|
104
|
+
setIoState(`Error: ${error.message}`);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
ioRef.current.on('ready', handleReady);
|
|
108
|
+
ioRef.current.on('change', handleChange);
|
|
109
|
+
ioRef.current.on(channel_tag, handleChannelMessage);
|
|
110
|
+
ioRef.current.on('error', handleError);
|
|
111
|
+
|
|
112
|
+
return () => {
|
|
113
|
+
ioRef.current.destroy();
|
|
114
|
+
console.log('IO instance destroyed.');
|
|
115
|
+
ioRef.current = null;
|
|
116
|
+
};
|
|
117
|
+
}, []);
|
|
118
|
+
|
|
119
|
+
const sendMessage = () => {
|
|
120
|
+
if (input.trim()) {
|
|
121
|
+
const msgObj = { text: input, cid: ioRef.current.cid };
|
|
122
|
+
ioRef.current.signal(channel_tag, msgObj);
|
|
123
|
+
setInput('date' + Date.now());
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const ioStateStyle = {
|
|
128
|
+
color: ioState === 'ready' ? 'green' : 'red',
|
|
129
|
+
fontWeight: 'bold',
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<div className="App">
|
|
134
|
+
<h1>React Chat Example</h1>
|
|
135
|
+
<div>URL: {url}</div>
|
|
136
|
+
<div>Channel: {channel_tag}</div>
|
|
137
|
+
<div>IO State: <span style={ioStateStyle}>{ioState}</span></div>
|
|
138
|
+
<div>Client ID: {cid}</div>
|
|
139
|
+
<div>IO Instances: {counts.instances}</div>
|
|
140
|
+
<div>WebSockets Created: {counts.websockets}</div>
|
|
141
|
+
<div className="messages">
|
|
142
|
+
{messages.map((msg, index) => (
|
|
143
|
+
<div key={index}>{msg}</div>
|
|
144
|
+
))}
|
|
145
|
+
<div ref={messagesEndRef} />
|
|
146
|
+
</div>
|
|
147
|
+
<div className="input-area">
|
|
148
|
+
<input
|
|
149
|
+
type="text"
|
|
150
|
+
value={input}
|
|
151
|
+
onChange={(e) => setInput(e.target.value)}
|
|
152
|
+
onKeyUp={(e) => e.key === 'Enter' && sendMessage()}
|
|
153
|
+
disabled={ioState !== 'ready'}
|
|
154
|
+
/>
|
|
155
|
+
<button onClick={sendMessage} disabled={ioState !== 'ready'}>
|
|
156
|
+
Send
|
|
157
|
+
</button>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export default App;
|
|
164
|
+
```
|
|
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
|
+

|
|
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
|
+
|
|
14
574
|
|
|
15
|
-
## IOSignal Client
|
|
16
575
|
|
|
17
576
|
### Browser client : ESM
|
|
18
577
|
|