Skip to content

Commit 10ddc40

Browse files
authored
feat: add useWebSocket composable function (#21)
* feat: implement basic websocket connection * docs: added websocket function to docs * docs: added websocket docs links
1 parent c2e6df8 commit 10ddc40

File tree

7 files changed

+123
-0
lines changed

7 files changed

+123
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Each composition function is designed to degrade gracefully so you can safely us
4646
- [Preferred Color Scheme](https://logaretm.github.io/vue-use-web/guide/preferred-color-scheme.html).
4747
- [Preferred Languages](https://logaretm.github.io/vue-use-web/guide/preferred-languages.html).
4848
- [Script](https://logaretm.github.io/vue-use-web/guide/script.html).
49+
- [WebSocket](https://logaretm.github.io/vue-use-web/guide/websocket.md).
4950
- [Window Scroll Position](https://logaretm.github.io/vue-use-web/guide/scroll-position.html).
5051
- [Window Size](https://logaretm.github.io/vue-use-web/guide/window-size.html).
5152
- Bluetooth (WIP).

docs/.vuepress/config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ module.exports = {
7373
'preferred-languages',
7474
'script',
7575
'scroll-position',
76+
'websocket',
7677
'window-size'
7778
],
7879
'/examples/': []

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ npm install @vue/composition-api vue-use-web
5454
- [Preferred Color Scheme](./guide/preferred-color-scheme.md).
5555
- [Preferred Languages](./guide/preferred-languages.md).
5656
- [Script](./guide/script.md).
57+
- [WebSocket](./guide/websocket.md).
5758
- [Window Scroll Position](./guide/scroll-position.md).
5859
- [Window Size](./guide/window-size.md).
5960
- Bluetooth <Badge text="WIP" type="warn" />.

docs/guide/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ These are the currently implemented Web APIs and the planned ones.
3838
- [Preferred Color Scheme](./preferred-color-scheme.md).
3939
- [Preferred Languages](./preferred-languages.md).
4040
- [Script](./script.md).
41+
- [WebSocket](./guide/websocket.md).
4142
- [Window Scroll Position](./scroll-position.md).
4243
- [Window Size](./window-size.md).
4344
- Bluetooth <Badge text="WIP" type="warn" />.

docs/guide/websocket.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Web Sockets
2+
3+
This functions provides simple websocket client capabilities.
4+
5+
## State
6+
7+
The `useWebSocket` function exposes the following reactive state:
8+
9+
```js
10+
import { useWebSocket } from 'vue-use-web';
11+
12+
const { state, data } = useWebSocket('ws://websocketurl');
13+
```
14+
15+
| State | Type | Description |
16+
| ----- | ------------- | ------------------------------------------------------------------------------------------------------- |
17+
| state | `Ref<string>` | The current websocket state, can be only one of: 'OPEN', 'CONNECTING', 'CLOSING', 'CLOSED' |
18+
| data | `Ref<object>` | Reference to the latest data received via the websocket, can be watched to respond to incoming messages |
19+
20+
## Methods
21+
22+
`useWebSocket` exposes the following methods:
23+
24+
```js
25+
import { useWebSocket } from 'vue-use-web';
26+
27+
const { send, close } = useWebSocket('ws://websocketurl');
28+
```
29+
30+
| Method | Signature | Description |
31+
| ------ | ------------------------------------------ | -------------------------------------------- |
32+
| send | `(data: any) => void` | Sends data through the websocket connection. |
33+
| close | `(code?: number, reason?: string) => void` | Closes the websocket connection gracefully. |
34+
35+
## Example
36+
37+
```vue
38+
<template>
39+
<div>
40+
<input type="text" v-model="message" />
41+
<button @click="send(message)">Send</button>
42+
<button @click="close()">Close</button>
43+
State: {{ state }}
44+
List of messages:
45+
<pre>{{ messages }}</pre>
46+
</div>
47+
</template>
48+
49+
<script>
50+
import { ref, watch } from '@vue/composition-api';
51+
import { useWebSocket } from 'vue-use-web';
52+
53+
export default {
54+
setup() {
55+
const { data, state, send, close } = useWebSocket('ws://demos.kaazing.com/echo');
56+
const message = ref('');
57+
const messages = ref([]);
58+
watch(
59+
data,
60+
val => {
61+
messages.value.push(val);
62+
},
63+
{ lazy: true }
64+
);
65+
66+
return { state, send, close, data, message, messages };
67+
}
68+
};
69+
</script>
70+
```
71+
72+
## Demo
73+
74+
TODO: Cool Chat app maybe

src/WebSocket.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { ref, onMounted, onUnmounted, Ref } from '@vue/composition-api';
2+
3+
export function useWebSocket(url: string) {
4+
const data: Ref<any> = ref(null);
5+
const state: Ref<'OPEN' | 'CONNECTING' | 'CLOSING' | 'CLOSED'> = ref('CONNECTING');
6+
let ws: WebSocket;
7+
const close: typeof ws.close = function close(code, reason) {
8+
if (!ws) return;
9+
10+
ws.close(code, reason);
11+
};
12+
13+
const send: typeof ws.send = function send(data) {
14+
if (!ws) return;
15+
16+
ws.send(data);
17+
};
18+
19+
onMounted(() => {
20+
ws = new WebSocket(url);
21+
ws.onopen = () => {
22+
state.value = 'OPEN';
23+
};
24+
25+
ws.onclose = ws.onerror = () => {
26+
state.value = 'CLOSED';
27+
};
28+
29+
ws.onmessage = (e: MessageEvent) => {
30+
data.value = e.data;
31+
};
32+
});
33+
34+
onUnmounted(() => {
35+
ws.close();
36+
});
37+
38+
return {
39+
data,
40+
state,
41+
close,
42+
send
43+
};
44+
}

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ export * from './Network';
1515
export * from './PreferredColorScheme';
1616
export * from './PreferredLanguages';
1717
export * from './Script';
18+
export * from './WebSocket';
1819
export * from './WindowScrollPosition';
1920
export * from './WindowSize';

0 commit comments

Comments
 (0)