Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 0 additions & 23 deletions .eslintrc.js

This file was deleted.

2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
16.15.0
22
237 changes: 210 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# vue-native-websocket · [![Build Status](https://travis-ci.org/nathantsoi/vue-native-websocket.svg?branch=master)](https://travis-ci.org/nathantsoi/vue-native-websocket) [![npm version](https://img.shields.io/npm/v/vue-native-websocket.svg?style=flat)](https://www.npmjs.com/package/vue-native-websocket)

native websocket implementation for Vuejs 2 and Vuex
native websocket implementation for Vue 3 with Vuex and Pinia support

## Install

Expand All @@ -14,48 +14,70 @@ yarn add vue-native-websocket
npm install vue-native-websocket --save
```

**Vue 3 Support**

This library supports Vue 3. For legacy Vue 2 support, please use version 2.x.

## Usage

#### Configuration

Automatic socket connection from an URL string

```js
import { createApp } from 'vue'
import VueNativeSock from "vue-native-websocket";
Vue.use(VueNativeSock, "ws://localhost:9090");

const app = createApp({})
app.use(VueNativeSock, "ws://localhost:9090");
```

Enable Vuex integration, where `'./store'` is your local apps store:

```js
import { createApp } from 'vue'
import store from "./store";
Vue.use(VueNativeSock, "ws://localhost:9090", { store: store });

const app = createApp({})
app.use(VueNativeSock, "ws://localhost:9090", { store: store });
```

Set sub-protocol, this is optional option and default is empty string.

```js
import { createApp } from 'vue'
import VueNativeSock from "vue-native-websocket";
Vue.use(VueNativeSock, "ws://localhost:9090", { protocol: "my-protocol" });

const app = createApp({})
app.use(VueNativeSock, "ws://localhost:9090", { protocol: "my-protocol" });
```

Optionally enable JSON message passing:

```js
Vue.use(VueNativeSock, "ws://localhost:9090", { format: "json" });
import { createApp } from 'vue'

const app = createApp({})
app.use(VueNativeSock, "ws://localhost:9090", { format: "json" });
```

JSON message passing with a store:

```js
import { createApp } from 'vue'
import store from "./store";
Vue.use(VueNativeSock, "ws://localhost:9090", { store: store, format: "json" });

const app = createApp({})
app.use(VueNativeSock, "ws://localhost:9090", { store: store, format: "json" });
```

Enable ws reconnect automatically:

```js
Vue.use(VueNativeSock, "ws://localhost:9090", {
import { createApp } from 'vue'

const app = createApp({})
app.use(VueNativeSock, "ws://localhost:9090", {
reconnection: true, // (Boolean) whether to reconnect automatically (false)
reconnectionAttempts: 5, // (Number) number of reconnection attempts before giving up (Infinity),
reconnectionDelay: 3000, // (Number) how long to initially wait before attempting a new (1000)
Expand All @@ -65,10 +87,16 @@ Vue.use(VueNativeSock, "ws://localhost:9090", {
Manage connection manually:

```js
Vue.use(VueNativeSock, "ws://localhost:9090", {
import { createApp } from 'vue'

const app = createApp({})
app.use(VueNativeSock, "ws://localhost:9090", {
connectManually: true,
});
const vm = new Vue();

// Mount your app
const vm = app.mount('#app')

// Connect to the websocket target specified in the configuration
vm.$connect();
// Connect to an alternative websocket URL and Options e.g.
Expand All @@ -77,10 +105,10 @@ vm.$connect("ws://localhost:9090/alternative/connection/", { format: "json" });
vm.$disconnect();
```

#### On Vuejs instance usage
#### On Vue instance usage

```js
var vm = new Vue({
export default {
methods: {
clickButton: function (val) {
// $socket is [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) instance
Expand All @@ -89,7 +117,7 @@ var vm = new Vue({
this.$socket.sendObj({ awesome: "data" });
},
},
});
}
```

#### Dynamic socket event listeners
Expand Down Expand Up @@ -131,12 +159,10 @@ Handle all the data in the `SOCKET_ONMESSAGE` mutation.
Reconect events will commit mutations `SOCKET_RECONNECT` and `SOCKET_RECONNECT_ERROR`.

```js
import Vue from 'vue'
import Vuex from 'vuex'
import { createApp } from 'vue'
import { createStore } from 'vuex'

Vue.use(Vuex);

export default new Vuex.Store({
const store = createStore({
state: {
socket: {
isConnected: false,
Expand All @@ -146,7 +172,6 @@ export default new Vuex.Store({
},
mutations:{
SOCKET_ONOPEN (state, event) {
Vue.prototype.$socket = event.currentTarget
state.socket.isConnected = true
},
SOCKET_ONCLOSE (state, event) {
Expand All @@ -169,12 +194,13 @@ export default new Vuex.Store({
},
actions: {
sendMessage: function(context, message) {
.....
Vue.prototype.$socket.sendObj(message)
.....
// Access via this.$socket in your component
// this.$socket.sendObj(message)
}
}
})

export default store
```

##### With custom mutation names
Expand All @@ -198,8 +224,7 @@ export {
};

// file source: store.js v2
import Vue from "vue";
import Vuex from "vuex";
import { createStore } from "vuex";
import {
SOCKET_ONOPEN,
SOCKET_ONCLOSE,
Expand All @@ -209,9 +234,7 @@ import {
SOCKET_RECONNECT_ERROR,
} from "./mutation-types";

Vue.use(Vuex);

export default new Vuex.Store({
export default createStore({
state: {
socket: {
isConnected: false,
Expand Down Expand Up @@ -244,6 +267,7 @@ export default new Vuex.Store({
});

// index.js
import { createApp } from 'vue'
import store from "./store";
import {
SOCKET_ONOPEN,
Expand All @@ -263,12 +287,171 @@ const mutations = {
SOCKET_RECONNECT_ERROR,
};

Vue.use(VueNativeSock, "ws://localhost:9090", {
const app = createApp({})
app.use(VueNativeSock, "ws://localhost:9090", {
store: store,
mutations: mutations,
});
```

#### Pinia Store integration

vue-native-websocket supports Pinia stores through the `passToStoreHandler` option, which allows custom integration with any state management solution.

##### Basic Pinia Integration

```js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import VueNativeSock from 'vue-native-websocket'
import { useSocketStore } from './stores/socket'

const app = createApp({})
const pinia = createPinia()
app.use(pinia)

// Create a custom handler for Pinia integration
const piniaHandler = (eventName, event) => {
const socketStore = useSocketStore()

// Handle socket events with Pinia store methods
switch (eventName) {
case 'SOCKET_ONOPEN':
socketStore.setConnected(true)
socketStore.setSocket(event.currentTarget)
break
case 'SOCKET_ONCLOSE':
socketStore.setConnected(false)
break
case 'SOCKET_ONERROR':
socketStore.setError(event)
break
case 'SOCKET_ONMESSAGE':
socketStore.setMessage(event.data)
break
case 'SOCKET_RECONNECT':
socketStore.setReconnectCount(event)
break
case 'SOCKET_RECONNECT_ERROR':
socketStore.setReconnectError(true)
break
}
}

app.use(VueNativeSock, 'ws://localhost:9090', {
passToStoreHandler: piniaHandler
})
```

##### Pinia Store Definition

```js
// stores/socket.js
import { defineStore } from 'pinia'

export const useSocketStore = defineStore('socket', {
state: () => ({
isConnected: false,
message: '',
reconnectError: false,
reconnectCount: 0,
socket: null,
error: null
}),

actions: {
setConnected(status) {
this.isConnected = status
},

setSocket(socket) {
this.socket = socket
},

setMessage(message) {
this.message = message
},

setError(error) {
this.error = error
},

setReconnectError(status) {
this.reconnectError = status
},

setReconnectCount(count) {
this.reconnectCount = count
}
}
})
```

##### Advanced Pinia Integration with JSON Format

For more advanced usage with JSON message format and actions:

```js
const advancedPiniaHandler = (eventName, event) => {
if (!eventName.startsWith('SOCKET_')) return

const socketStore = useSocketStore()

// Handle connection events
if (eventName === 'SOCKET_ONOPEN') {
socketStore.setConnected(true)
socketStore.setSocket(event.currentTarget)
return
}

if (eventName === 'SOCKET_ONCLOSE') {
socketStore.setConnected(false)
return
}

if (eventName === 'SOCKET_ONERROR') {
socketStore.setError(event)
return
}

// Handle messages with JSON format
if (eventName === 'SOCKET_ONMESSAGE' && event.data) {
try {
const message = JSON.parse(event.data)

// If message has an action, call the corresponding store action
if (message.action) {
const actionName = message.action
if (typeof socketStore[actionName] === 'function') {
socketStore[actionName](message)
}
return
}

// Otherwise just store the message
socketStore.setMessage(message)
} catch (e) {
// If not JSON, store as plain text
socketStore.setMessage(event.data)
}
}

// Handle reconnection events
if (eventName === 'SOCKET_RECONNECT') {
socketStore.setReconnectCount(event)
}

if (eventName === 'SOCKET_RECONNECT_ERROR') {
socketStore.setReconnectError(true)
}
}

app.use(VueNativeSock, 'ws://localhost:9090', {
format: 'json',
passToStoreHandler: advancedPiniaHandler
})
```

##### With `format: 'json'` enabled

All data passed through the websocket is expected to be JSON.
Expand Down
Loading