mirror of
https://github.com/MetinSeylan/Vue-Socket.io.git
synced 2025-04-16 15:21:28 +02:00
Merge 977f56102b
into 640dfc044c
This commit is contained in:
commit
f91bcca091
7 changed files with 324 additions and 451 deletions
192
README.md
192
README.md
|
@ -2,7 +2,7 @@
|
||||||
<a href="https://github.com/MetinSeylan/Vue-Socket.io" target="_blank">
|
<a href="https://github.com/MetinSeylan/Vue-Socket.io" target="_blank">
|
||||||
<img width="250" src="https://raw.githubusercontent.com/MetinSeylan/Vue-Socket.io/master/docs/logo.png">
|
<img width="250" src="https://raw.githubusercontent.com/MetinSeylan/Vue-Socket.io/master/docs/logo.png">
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://www.npmjs.com/package/vue-socket.io"><img src="https://img.shields.io/npm/v/vue-socket.io.svg"/> <img src="https://img.shields.io/npm/dt/vue-socket.io.svg"/></a>
|
<a href="https://www.npmjs.com/package/vue-socket.io"><img src="https://img.shields.io/npm/v/vue-socket.io.svg"/> <img src="https://img.shields.io/npm/dt/vue-socket.io.svg"/></a>
|
||||||
|
@ -16,6 +16,7 @@
|
||||||
<p>Vue-Socket.io is a socket.io integration for Vuejs, easy to use, supporting Vuex and component level socket consumer managements.<p>
|
<p>Vue-Socket.io is a socket.io integration for Vuejs, easy to use, supporting Vuex and component level socket consumer managements.<p>
|
||||||
|
|
||||||
###### Demo
|
###### Demo
|
||||||
|
|
||||||
- <a href="http://metinseylan.com/vuesocketio/" target="_blank">Chat Application</a>
|
- <a href="http://metinseylan.com/vuesocketio/" target="_blank">Chat Application</a>
|
||||||
- <a href="http://metinseylan.com" target="_blank">Car Tracking Application</a>
|
- <a href="http://metinseylan.com" target="_blank">Car Tracking Application</a>
|
||||||
|
|
||||||
|
@ -24,173 +25,148 @@ are you looking for old documentation? <a href="https://github.com/MetinSeylan/V
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
#### 🚀 Installation
|
#### 🚀 Installation
|
||||||
``` bash
|
|
||||||
|
```bash
|
||||||
npm install vue-socket.io --save
|
npm install vue-socket.io --save
|
||||||
```
|
```
|
||||||
##### Using Connection String
|
|
||||||
``` javascript
|
|
||||||
import Vue from 'vue'
|
|
||||||
import store from './store'
|
|
||||||
import App from './App.vue'
|
|
||||||
import VueSocketIO from 'vue-socket.io'
|
|
||||||
import SocketIO from "socket.io-client"
|
|
||||||
|
|
||||||
Vue.use(new VueSocketIO({
|
##### Using Connection String
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import Vue from 'vue';
|
||||||
|
import store from './store';
|
||||||
|
import App from './App.vue';
|
||||||
|
import VueSocketIO from 'vue-socket.io';
|
||||||
|
|
||||||
|
Vue.use(
|
||||||
|
new VueSocketIO({
|
||||||
debug: true,
|
debug: true,
|
||||||
connection: 'http://metinseylan.com:1992',
|
connection: 'http://metinseylan.com:1992',
|
||||||
vuex: {
|
vuex: {
|
||||||
store,
|
store,
|
||||||
actionPrefix: 'SOCKET_',
|
actionPrefix: 'SOCKET_',
|
||||||
mutationPrefix: 'SOCKET_'
|
mutationPrefix: 'SOCKET_'
|
||||||
},
|
},
|
||||||
options: { path: "/my-app/" } //Optional options
|
options: { path: '/my-app/' } //Optional options
|
||||||
}))
|
})
|
||||||
|
);
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
router,
|
router,
|
||||||
store,
|
store,
|
||||||
render: h => h(App)
|
render: h => h(App)
|
||||||
}).$mount('#app')
|
}).$mount('#app');
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Using socket.io-client Instance
|
##### Using socket.io-client Instance
|
||||||
``` javascript
|
|
||||||
import Vue from 'vue'
|
```javascript
|
||||||
import store from './store'
|
import Vue from 'vue';
|
||||||
import App from './App.vue'
|
import store from './store';
|
||||||
import VueSocketIO from 'vue-socket.io'
|
import App from './App.vue';
|
||||||
import SocketIO from "socket.io-client"
|
import VueSocketIO from 'vue-socket.io';
|
||||||
|
import SocketIO from 'socket.io-client';
|
||||||
|
|
||||||
const options = { path: '/my-app/' }; //Options object to pass into SocketIO
|
const options = { path: '/my-app/' }; //Options object to pass into SocketIO
|
||||||
|
|
||||||
Vue.use(new VueSocketIO({
|
Vue.use(
|
||||||
|
new VueSocketIO({
|
||||||
debug: true,
|
debug: true,
|
||||||
connection: SocketIO('http://metinseylan.com:1992', options), //options object is Optional
|
connection: SocketIO('http://metinseylan.com:1992', options), //options object is Optional
|
||||||
vuex: {
|
vuex: {
|
||||||
store,
|
store,
|
||||||
actionPrefix: "SOCKET_",
|
actionPrefix: 'SOCKET_',
|
||||||
mutationPrefix: "SOCKET_"
|
mutationPrefix: 'SOCKET_'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
router,
|
router,
|
||||||
store,
|
store,
|
||||||
render: h => h(App)
|
render: h => h(App)
|
||||||
}).$mount('#app')
|
}).$mount('#app');
|
||||||
```
|
```
|
||||||
|
|
||||||
**Parameters**|**Type's**|**Default**|**Required**|**Description**
|
| **Parameters** | **Type's** | **Default** | **Required** | **Description** |
|
||||||
-----|-----|-----|-----|-----
|
| ----------------------------------- | ----------------------- | ----------- | ------------ | ------------------------------------------------- |
|
||||||
debug|Boolean|`false`|Optional|Enable logging for debug
|
| debug | Boolean | `false` | Optional | Enable logging for debug |
|
||||||
connection|String/Socket.io-client|`null`|Required|Websocket server url or socket.io-client instance
|
| connection | String/Socket.io-client | `null` | Required | Websocket server url or socket.io-client instance |
|
||||||
vuex.store|Vuex|`null`|Optional|Vuex store instance
|
| vuex.store | Vuex | `null` | Optional | Vuex store instance |
|
||||||
vuex.actionPrefix|String|`null`|Optional|Prefix for emitting server side vuex actions
|
| vuex.actionPrefix | String | `null` | Optional | Prefix for emitting server side vuex actions |
|
||||||
vuex.mutationPrefix|String |`null`|Optional|Prefix for emitting server side vuex mutations
|
| vuex.mutationPrefix | String | `null` | Optional | Prefix for emitting server side vuex mutations |
|
||||||
vuex.options.useConnectionNamespace |Boolean|`false`|Optional|Use more than one connection namespace
|
| vuex.options.useConnectionNamespace | Boolean | `false` | Optional | Use more than one connection namespace |
|
||||||
|
|
||||||
#### 🌈 Component Level Usage
|
#### 🌈 Component Level Usage
|
||||||
|
|
||||||
<p>If you want to listen socket events from component side, you need to add `sockets` object in Vue component, and every function will start to listen events, depends on object key</p>
|
<p>If you want to listen socket events from component side, you need to add `sockets` object in Vue component, and every function will start to listen events, depends on object key</p>
|
||||||
|
|
||||||
``` javascript
|
```javascript
|
||||||
new Vue({
|
new Vue({
|
||||||
sockets: {
|
sockets: {
|
||||||
connect: function () {
|
connect: function() {
|
||||||
console.log('socket connected')
|
console.log('socket connected');
|
||||||
},
|
|
||||||
customEmit: function (data) {
|
|
||||||
console.log('this method was fired by the socket server. eg: io.emit("customEmit", data)')
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
customEmit: function(data) {
|
||||||
clickButton: function (data) {
|
console.log('this method was fired by the socket server. eg: io.emit("customEmit", data)');
|
||||||
// $socket is socket.io-client instance
|
|
||||||
this.$socket.emit('emit_method', data)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
},
|
||||||
|
methods: {
|
||||||
|
clickButton: function(data) {
|
||||||
|
// $socket is socket.io-client instance
|
||||||
|
this.$socket.emit('emit_method', data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Dynamic Listeners
|
##### Dynamic Listeners
|
||||||
|
|
||||||
<p>If you need consuming events dynamically in runtime, you can use `subscribe` and `unsubscribe` methods in Vue component</p>
|
<p>If you need consuming events dynamically in runtime, you can use `subscribe` and `unsubscribe` methods in Vue component</p>
|
||||||
|
|
||||||
``` javascript
|
```javascript
|
||||||
this.sockets.subscribe('EVENT_NAME', (data) => {
|
this.sockets.subscribe('EVENT_NAME', data => {
|
||||||
this.msg = data.message;
|
this.msg = data.message;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.sockets.unsubscribe('EVENT_NAME');
|
this.sockets.unsubscribe('EVENT_NAME');
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 🏆 Vuex Integration
|
#### 🏆 Vuex Integration
|
||||||
<p>When you set store parameter in installation, `Vue-Socket.io` will start sending events to Vuex store. If you set both prefix for vuex, you can use `actions` and `mutations` at the same time. But, best way to use is just `actions`</p>
|
|
||||||
|
|
||||||
``` javascript
|
<p>When you set store parameter in installation, `Vue-Socket.io` will start sending events to Vuex store. The prefix for mutations and actions are both optional and will default to none. The prefix may be useful in differentiating what type of event should be sent to the store in the case of an action and mutation with the same name.</p>
|
||||||
import Vue from 'vue'
|
|
||||||
import Vuex from 'vuex'
|
|
||||||
|
|
||||||
Vue.use(Vuex)
|
```javascript
|
||||||
|
import Vue from 'vue';
|
||||||
|
import Vuex from 'vuex';
|
||||||
|
|
||||||
|
Vue.use(Vuex);
|
||||||
|
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
state: {},
|
state: {},
|
||||||
mutations: {
|
mutations: {
|
||||||
"<MUTATION_PREFIX><EVENT_NAME>"() {
|
'<MUTATION_PREFIX><EVENT_NAME>'() {
|
||||||
// do something
|
// do something
|
||||||
}
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
"<ACTION_PREFIX><EVENT_NAME>"() {
|
|
||||||
// do something
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
},
|
||||||
|
actions: {
|
||||||
|
'<ACTION_PREFIX><EVENT_NAME>'() {
|
||||||
|
// do something
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 🏆 Connection Namespace
|
##### Vuex Namespaced Modules
|
||||||
<p>When you need to handle more than one namespaced connection, you need to set the `useConnectionNamespace` property of
|
|
||||||
the options object to true. What this does is telling the plugin that you are going to be using more than one namespaced connection and you want to put every connection in their own `$socket` key.</p>
|
|
||||||
|
|
||||||
``` javascript
|
<p>When using namespaced modules, the prefix, if one exists, will be parsed into the action name. For example, if the emitted event it `jobs/runTask` and the action prefix is `SOCKET_`, then the vuex action should be `SOCKET_runTask` in the jobs namespace. In this example the vuex store will receive the dispatched action: `jobs/SOCKET_runTask`.</p>
|
||||||
import Vue from 'vue'
|
|
||||||
import store from './store'
|
|
||||||
import App from './App.vue'
|
|
||||||
import VueSocketIO from 'vue-socket.io'
|
|
||||||
|
|
||||||
Vue.use(new VueSocketIO({
|
|
||||||
debug: true,
|
|
||||||
connection: 'http://metinseylan.com:1992/mynamespace',
|
|
||||||
vuex: {
|
|
||||||
store,
|
|
||||||
options: {
|
|
||||||
useConnectionNamespace: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
options: { path: "/my-app/" } //Optional options
|
|
||||||
}))
|
|
||||||
|
|
||||||
new Vue({
|
|
||||||
router,
|
|
||||||
store,
|
|
||||||
render: h => h(App)
|
|
||||||
}).$mount('#app')
|
|
||||||
```
|
|
||||||
|
|
||||||
Then use it like this:
|
|
||||||
|
|
||||||
``` javascript
|
|
||||||
Vue.$socket.mynamespace.emit('emit_method', data)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Stargazers over time
|
## Stargazers over time
|
||||||
|
|
||||||
[](https://starcharts.herokuapp.com/MetinSeylan/Vue-Socket.io)
|
[](https://starcharts.herokuapp.com/MetinSeylan/Vue-Socket.io)
|
||||||
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/MetinSeylan/Vue-Socket.io" target="_blank">
|
<a href="https://github.com/MetinSeylan/Vue-Socket.io" target="_blank">
|
||||||
<img src="https://media.giphy.com/media/11jlnltQgUi2mQ/giphy.gif">
|
<img src="https://media.giphy.com/media/11jlnltQgUi2mQ/giphy.gif">
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
8
dist/vue-socketio.js
vendored
8
dist/vue-socketio.js
vendored
File diff suppressed because one or more lines are too long
231
src/emitter.js
231
src/emitter.js
|
@ -1,136 +1,117 @@
|
||||||
import Logger from './logger';
|
import Logger from './logger';
|
||||||
|
|
||||||
export default class EventEmitter{
|
export default class EventEmitter {
|
||||||
|
constructor(vuex = {}) {
|
||||||
|
Logger.info(vuex ? `Vuex adapter enabled` : `Vuex adapter disabled`);
|
||||||
|
this.store = vuex.store;
|
||||||
|
this.actionPrefix = vuex.actionPrefix;
|
||||||
|
this.mutationPrefix = vuex.mutationPrefix;
|
||||||
|
this.listeners = new Map();
|
||||||
|
}
|
||||||
|
|
||||||
constructor(vuex = {}){
|
/**
|
||||||
Logger.info(vuex ? `Vuex adapter enabled` : `Vuex adapter disabled`);
|
* register new event listener with vuejs component instance
|
||||||
Logger.info(vuex.mutationPrefix ? `Vuex socket mutations enabled` : `Vuex socket mutations disabled`);
|
* @param event
|
||||||
Logger.info(vuex ? `Vuex socket actions enabled` : `Vuex socket actions disabled`);
|
* @param callback
|
||||||
this.store = vuex.store;
|
* @param component
|
||||||
this.actionPrefix = vuex.actionPrefix ? vuex.actionPrefix : 'SOCKET_';
|
*/
|
||||||
this.mutationPrefix = vuex.mutationPrefix;
|
addListener(event, callback, component) {
|
||||||
this.listeners = new Map();
|
if (typeof callback === 'function') {
|
||||||
|
if (!this.listeners.has(event)) this.listeners.set(event, []);
|
||||||
|
this.listeners.get(event).push({ callback, component });
|
||||||
|
|
||||||
|
Logger.info(`#${event} subscribe, component: ${component.$options.name}`);
|
||||||
|
} else {
|
||||||
|
throw new Error(`callback must be a function`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* remove a listenler
|
||||||
|
* @param event
|
||||||
|
* @param component
|
||||||
|
*/
|
||||||
|
removeListener(event, component) {
|
||||||
|
if (this.listeners.has(event)) {
|
||||||
|
const listeners = this.listeners.get(event).filter(listener => listener.component !== component);
|
||||||
|
|
||||||
|
if (listeners.length > 0) {
|
||||||
|
this.listeners.set(event, listeners);
|
||||||
|
} else {
|
||||||
|
this.listeners.delete(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.info(`#${event} unsubscribe, component: ${component.$options.name}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* broadcast incoming event to components
|
||||||
|
* @param event
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
emit(event, args) {
|
||||||
|
if (this.listeners.has(event)) {
|
||||||
|
Logger.info(`Broadcasting: #${event}, Data:`, args);
|
||||||
|
|
||||||
|
this.listeners.get(event).forEach(listener => {
|
||||||
|
listener.callback.call(listener.component, args);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
if (event !== 'ping' && event !== 'pong') {
|
||||||
* register new event listener with vuejs component instance
|
this.dispatchStore(event, args);
|
||||||
* @param event
|
|
||||||
* @param callback
|
|
||||||
* @param component
|
|
||||||
*/
|
|
||||||
addListener(event, callback, component){
|
|
||||||
|
|
||||||
if(typeof callback === 'function'){
|
|
||||||
|
|
||||||
if (!this.listeners.has(event)) this.listeners.set(event, []);
|
|
||||||
this.listeners.get(event).push({ callback, component });
|
|
||||||
|
|
||||||
Logger.info(`#${event} subscribe, component: ${component.$options.name}`);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
throw new Error(`callback must be a function`);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* remove a listenler
|
* dispatching vuex actions
|
||||||
* @param event
|
* @param event
|
||||||
* @param component
|
* @param args
|
||||||
*/
|
*/
|
||||||
removeListener(event, component){
|
dispatchStore(event, args) {
|
||||||
|
if (this.store) {
|
||||||
if(this.listeners.has(event)){
|
if (this.store._actions) {
|
||||||
|
let action_name = event;
|
||||||
const listeners = this.listeners.get(event).filter(listener => (
|
|
||||||
listener.component !== component
|
|
||||||
));
|
|
||||||
|
|
||||||
if (listeners.length > 0) {
|
|
||||||
this.listeners.set(event, listeners);
|
|
||||||
} else {
|
|
||||||
this.listeners.delete(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.info(`#${event} unsubscribe, component: ${component.$options.name}`);
|
|
||||||
|
|
||||||
|
if (!!this.actionPrefix) {
|
||||||
|
let namespace_sep_pos = event.lastIndexOf('/');
|
||||||
|
action_name =
|
||||||
|
namespace_sep_pos !== -1
|
||||||
|
? [event.slice(0, namespace_sep_pos + 1), this.actionPrefix, event.slice(namespace_sep_pos + 1)].join('')
|
||||||
|
: this.actionPrefix + event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (let key in this.store._actions) {
|
||||||
|
if (key === action_name) {
|
||||||
|
Logger.info(`Dispatching Action: ${key}, Data:`, args);
|
||||||
|
|
||||||
|
this.store.dispatch(key, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.mutationPrefix) {
|
||||||
|
let mutation_name = event;
|
||||||
|
|
||||||
|
if (!!this.mutationPrefix) {
|
||||||
|
let namespace_sep_pos = event.lastIndexOf('/');
|
||||||
|
mutation_name =
|
||||||
|
namespace_sep_pos !== -1
|
||||||
|
? [event.slice(0, namespace_sep_pos + 1), this.mutationPrefix, event.slice(namespace_sep_pos + 1)].join(
|
||||||
|
''
|
||||||
|
)
|
||||||
|
: this.mutationPrefix + event;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let key in this.store._mutations) {
|
||||||
|
if (key === mutation_name) {
|
||||||
|
Logger.info(`Committing Mutation: ${key}, Data:`, args);
|
||||||
|
|
||||||
|
this.store.commit(key, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
}
|
||||||
* broadcast incoming event to components
|
|
||||||
* @param event
|
|
||||||
* @param args
|
|
||||||
*/
|
|
||||||
emit(event, args){
|
|
||||||
|
|
||||||
if(this.listeners.has(event)){
|
|
||||||
|
|
||||||
Logger.info(`Broadcasting: #${event}, Data:`, args);
|
|
||||||
|
|
||||||
this.listeners.get(event).forEach((listener) => {
|
|
||||||
listener.callback.call(listener.component, args);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if(event !== 'ping' && event !== 'pong') {
|
|
||||||
this.dispatchStore(event, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* dispatching vuex actions
|
|
||||||
* @param event
|
|
||||||
* @param args
|
|
||||||
*/
|
|
||||||
dispatchStore(event, args){
|
|
||||||
|
|
||||||
if(this.store && this.store._actions){
|
|
||||||
|
|
||||||
let prefixed_event = this.actionPrefix + event;
|
|
||||||
|
|
||||||
for (let key in this.store._actions) {
|
|
||||||
|
|
||||||
let action = key.split('/').pop();
|
|
||||||
|
|
||||||
if(action === prefixed_event) {
|
|
||||||
|
|
||||||
Logger.info(`Dispatching Action: ${key}, Data:`, args);
|
|
||||||
|
|
||||||
this.store.dispatch(key, args);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.mutationPrefix) {
|
|
||||||
|
|
||||||
let prefixed_event = this.mutationPrefix + event;
|
|
||||||
|
|
||||||
for (let key in this.store._mutations) {
|
|
||||||
|
|
||||||
let mutation = key.split('/').pop();
|
|
||||||
|
|
||||||
if(mutation === prefixed_event) {
|
|
||||||
|
|
||||||
Logger.info(`Commiting Mutation: ${key}, Data:`, args);
|
|
||||||
|
|
||||||
this.store.commit(key, args);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
97
src/index.js
97
src/index.js
|
@ -1,61 +1,35 @@
|
||||||
import Mixin from "./mixin";
|
import Mixin from './mixin';
|
||||||
import Logger from "./logger";
|
import Logger from './logger';
|
||||||
import Listener from "./listener";
|
import Listener from './listener';
|
||||||
import Emitter from "./emitter";
|
import Emitter from './emitter';
|
||||||
import SocketIO from "socket.io-client";
|
import SocketIO from 'socket.io-client';
|
||||||
|
|
||||||
export default class VueSocketIO {
|
export default class VueSocketIO {
|
||||||
|
/**
|
||||||
|
* lets take all resource
|
||||||
|
* @param io
|
||||||
|
* @param vuex
|
||||||
|
* @param debug
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
constructor({ connection, vuex, debug, options }) {
|
||||||
|
Logger.debug = debug;
|
||||||
|
this.io = this.connect(connection, options);
|
||||||
|
this.emitter = new Emitter(vuex);
|
||||||
|
this.listener = new Listener(this.io, this.emitter);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lets take all resource
|
* Vue.js entry point
|
||||||
* @param io
|
* @param Vue
|
||||||
* @param vuex
|
*/
|
||||||
* @param debug
|
install(Vue) {
|
||||||
* @param options
|
Vue.prototype.$socket = this.io;
|
||||||
*/
|
Vue.prototype.$vueSocketIo = this;
|
||||||
constructor({connection, vuex, debug, options}){
|
Vue.mixin(Mixin);
|
||||||
|
|
||||||
Logger.debug = debug;
|
Logger.info('Vue-Socket.io plugin enabled');
|
||||||
this.io = this.connect(connection, options);
|
}
|
||||||
this.useConnectionNamespace = (options && options.useConnectionNamespace);
|
|
||||||
this.namespaceName = (options && options.namespaceName);
|
|
||||||
this.emitter = new Emitter(vuex);
|
|
||||||
this.listener = new Listener(this.io, this.emitter);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vue.js entry point
|
|
||||||
* @param Vue
|
|
||||||
*/
|
|
||||||
install(Vue){
|
|
||||||
|
|
||||||
const namespace = this.namespaceName || this.io.nsp.replace("/", "");
|
|
||||||
|
|
||||||
if (this.useConnectionNamespace) {
|
|
||||||
if (typeof Vue.prototype.$socket === "object") {
|
|
||||||
Vue.prototype.$socket = {
|
|
||||||
...Vue.prototype.$socket,
|
|
||||||
[namespace]: this.io
|
|
||||||
};
|
|
||||||
|
|
||||||
Vue.prototype.$vueSocketIo = {...Vue.prototype.$vueSocketIo, [namespace]: this};
|
|
||||||
} else {
|
|
||||||
Vue.prototype.$socket = {
|
|
||||||
[namespace]: this.io
|
|
||||||
};
|
|
||||||
Vue.prototype.$vueSocketIo = { [namespace]: this};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Vue.prototype.$socket = this.io;
|
|
||||||
Vue.prototype.$vueSocketIo = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vue.mixin(Mixin);
|
|
||||||
|
|
||||||
Logger.info('Vue-Socket.io plugin enabled');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* registering SocketIO instance
|
* registering SocketIO instance
|
||||||
|
@ -63,15 +37,16 @@ export default class VueSocketIO {
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
connect(connection, options) {
|
connect(connection, options) {
|
||||||
if (connection && typeof connection === "object") {
|
if (connection && typeof connection === 'object') {
|
||||||
Logger.info(`Received socket.io-client instance`);
|
Logger.info('Received socket.io-client instance');
|
||||||
|
|
||||||
return connection;
|
return connection;
|
||||||
} else if (typeof connection === "string") {
|
} else if (typeof connection === 'string') {
|
||||||
const io = SocketIO(connection, options);
|
Logger.info('Received connection string');
|
||||||
Logger.info(`Received connection string`);
|
|
||||||
return (this.io = io);
|
return (this.io = SocketIO(connection, options));
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Unsupported connection type");
|
throw new Error('Unsupported connection type');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,51 +1,48 @@
|
||||||
|
|
||||||
export default class VueSocketIOListener {
|
export default class VueSocketIOListener {
|
||||||
|
/**
|
||||||
|
* socket.io-client reserved event keywords
|
||||||
|
* @type {string[]}
|
||||||
|
*/
|
||||||
|
static staticEvents = [
|
||||||
|
'connect',
|
||||||
|
'error',
|
||||||
|
'disconnect',
|
||||||
|
'reconnect',
|
||||||
|
'reconnect_attempt',
|
||||||
|
'reconnecting',
|
||||||
|
'reconnect_error',
|
||||||
|
'reconnect_failed',
|
||||||
|
'connect_error',
|
||||||
|
'connect_timeout',
|
||||||
|
'connecting',
|
||||||
|
'ping',
|
||||||
|
'pong'
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
constructor(io, emitter) {
|
||||||
* socket.io-client reserved event keywords
|
this.io = io;
|
||||||
* @type {string[]}
|
this.register();
|
||||||
*/
|
this.emitter = emitter;
|
||||||
static staticEvents = [
|
}
|
||||||
'connect',
|
|
||||||
'error',
|
|
||||||
'disconnect',
|
|
||||||
'reconnect',
|
|
||||||
'reconnect_attempt',
|
|
||||||
'reconnecting',
|
|
||||||
'reconnect_error',
|
|
||||||
'reconnect_failed',
|
|
||||||
'connect_error',
|
|
||||||
'connect_timeout',
|
|
||||||
'connecting',
|
|
||||||
'ping',
|
|
||||||
'pong'
|
|
||||||
];
|
|
||||||
|
|
||||||
constructor(io, emitter){
|
/**
|
||||||
this.io = io;
|
* Listening all socket.io events
|
||||||
this.register();
|
*/
|
||||||
this.emitter = emitter;
|
register() {
|
||||||
}
|
this.io.onevent = packet => {
|
||||||
|
let [event, ...args] = packet.data;
|
||||||
|
|
||||||
/**
|
if (args.length === 1) args = args[0];
|
||||||
* Listening all socket.io events
|
|
||||||
*/
|
|
||||||
register(){
|
|
||||||
this.io.onevent = (packet) => {
|
|
||||||
let [event, ...args] = packet.data;
|
|
||||||
|
|
||||||
if(args.length === 1) args = args[0];
|
this.onEvent(event, args);
|
||||||
|
};
|
||||||
this.onEvent(event, args)
|
VueSocketIOListener.staticEvents.forEach(event => this.io.on(event, args => this.onEvent(event, args)));
|
||||||
};
|
}
|
||||||
VueSocketIOListener.staticEvents.forEach(event => this.io.on(event, args => this.onEvent(event, args)))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Broadcast all events to vuejs environment
|
|
||||||
*/
|
|
||||||
onEvent(event, args){
|
|
||||||
this.emitter.emit(event, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcast all events to vuejs environment
|
||||||
|
*/
|
||||||
|
onEvent(event, args) {
|
||||||
|
this.emitter.emit(event, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +1,27 @@
|
||||||
/**
|
/**
|
||||||
* shitty logger class
|
* shitty logger class
|
||||||
*/
|
*/
|
||||||
export default new class VueSocketIOLogger {
|
export default new (class VueSocketIOLogger {
|
||||||
|
constructor() {
|
||||||
|
this.debug = false;
|
||||||
|
this.prefix = '%cVue-Socket.io: ';
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
info(text, data = '') {
|
||||||
this.debug = false;
|
if (this.debug)
|
||||||
this.prefix = '%cVue-Socket.io: ';
|
window.console.info(this.prefix + `%c${text}`, 'color: blue; font-weight: 600', 'color: #333333', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
info(text, data = '') {
|
error() {
|
||||||
|
if (this.debug) window.console.error(this.prefix, ...arguments);
|
||||||
|
}
|
||||||
|
|
||||||
if(this.debug) window.console.info(this.prefix+`%c${text}`, 'color: blue; font-weight: 600', 'color: #333333', data);
|
warn() {
|
||||||
|
if (this.debug) window.console.warn(this.prefix, ...arguments);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
event(text, data = '') {
|
||||||
|
if (this.debug)
|
||||||
error() {
|
window.console.info(this.prefix + `%c${text}`, 'color: blue; font-weight: 600', 'color: #333333', data);
|
||||||
|
}
|
||||||
if(this.debug) window.console.error(this.prefix, ...arguments);
|
})();
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
warn() {
|
|
||||||
|
|
||||||
if(this.debug) window.console.warn(this.prefix, ...arguments);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
event(text, data = ''){
|
|
||||||
|
|
||||||
if(this.debug) window.console.info(this.prefix+`%c${text}`, 'color: blue; font-weight: 600', 'color: #333333', data);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
114
src/mixin.js
114
src/mixin.js
|
@ -1,88 +1,40 @@
|
||||||
export default {
|
export default {
|
||||||
|
/**
|
||||||
|
* Assign runtime callbacks
|
||||||
|
*/
|
||||||
|
beforeCreate() {
|
||||||
|
if (!this.sockets) this.sockets = {};
|
||||||
|
|
||||||
/**
|
this.sockets.subscribe = (event, callback) => {
|
||||||
* Assign runtime callbacks
|
this.$vueSocketIo.emitter.addListener(event, callback, this);
|
||||||
*/
|
};
|
||||||
beforeCreate(){
|
|
||||||
|
|
||||||
if(!this.sockets) this.sockets = {};
|
this.sockets.unsubscribe = event => {
|
||||||
|
this.$vueSocketIo.emitter.removeListener(event, this);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
if (typeof this.$vueSocketIo === 'object') {
|
/**
|
||||||
for (const namespace of Object.keys(this.$vueSocketIo)) {
|
* Register all socket events
|
||||||
this.sockets[namespace] = {
|
*/
|
||||||
subscribe: (event, callback) => {
|
mounted() {
|
||||||
this.$vueSocketIo[namespace].emitter.addListener(event, callback, this);
|
if (this.$options.sockets) {
|
||||||
},
|
Object.keys(this.$options.sockets).forEach(event => {
|
||||||
unsubscribe: (event) => {
|
if (event !== 'subscribe' && event !== 'unsubscribe') {
|
||||||
this.$vueSocketIo[namespace].emitter.removeListener(event, this);
|
this.$vueSocketIo.emitter.addListener(event, this.$options.sockets[event], this);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.$vueSocketIo.emitter.addListener(event, callback, this);
|
|
||||||
this.$vueSocketIo.emitter.removeListener(event, this);
|
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* Register all socket events
|
|
||||||
*/
|
|
||||||
mounted(){
|
|
||||||
|
|
||||||
if(this.$options.sockets){
|
|
||||||
|
|
||||||
if (typeof this.$vueSocketIo === 'object') {
|
|
||||||
for (const namespace of Object.keys(this.$vueSocketIo)) {
|
|
||||||
if (this.$options.sockets[namespace]) {
|
|
||||||
Object.keys(this.$options.sockets[namespace]).forEach(event => {
|
|
||||||
|
|
||||||
if(event !== 'subscribe' && event !== 'unsubscribe') {
|
|
||||||
this.$vueSocketIo[namespace].emitter.addListener(event, this.$options.sockets[namespace][event], this);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Object.keys(this.$options.sockets).forEach(event => {
|
|
||||||
|
|
||||||
if(event !== 'subscribe' && event !== 'unsubscribe') {
|
|
||||||
this.$vueSocketIo.emitter.addListener(event, this.$options.sockets[event], this);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* unsubscribe when component unmounting
|
|
||||||
*/
|
|
||||||
beforeDestroy(){
|
|
||||||
|
|
||||||
if(this.$options.sockets){
|
|
||||||
|
|
||||||
if (typeof this.$vueSocketIo === 'object') {
|
|
||||||
for (const namespace of Object.keys(this.$vueSocketIo)) {
|
|
||||||
if (this.$options.sockets[namespace]) {
|
|
||||||
Object.keys(this.$options.sockets[namespace]).forEach(event => {
|
|
||||||
|
|
||||||
this.$vueSocketIo[namespace].emitter.removeListener(event, this);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Object.keys(this.$options.sockets).forEach(event => {
|
|
||||||
|
|
||||||
this.$vueSocketIo.emitter.removeListener(event, this);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
}
|
/**
|
||||||
|
* unsubscribe when component unmounting
|
||||||
|
*/
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.$options.sockets) {
|
||||||
|
Object.keys(this.$options.sockets).forEach(event => {
|
||||||
|
this.$vueSocketIo.emitter.removeListener(event, this);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue