working web browser client (with quasar) uses json packets and specifically works with uci-websocket
parent
83ec3849dd
commit
b6be936f44
|
@ -0,0 +1,34 @@
|
|||
module.exports = {
|
||||
"ecmaFeatures": {
|
||||
"modules": true,
|
||||
"spread" : true,
|
||||
"restParams" : true
|
||||
},
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true,
|
||||
"mocha": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2017,
|
||||
"sourceType": "module",
|
||||
"parser": 'babel-eslint',
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"rules": {
|
||||
"indent": [
|
||||
"error",
|
||||
2
|
||||
],
|
||||
"no-console": 0,
|
||||
"semi": ["error", "never"],
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"unix"
|
||||
],
|
||||
"quotes": [
|
||||
"error",
|
||||
"single"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint',
|
||||
sourceType: 'module'
|
||||
},
|
||||
env: {
|
||||
browser: true
|
||||
},
|
||||
extends: [
|
||||
// https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
|
||||
// consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
|
||||
// 'plugin:vue/essential',
|
||||
// https://github.com/standard/standard/blob/master/docs/RULES-en.md
|
||||
'standard'
|
||||
],
|
||||
// required to lint *.vue files
|
||||
plugins: [
|
||||
// 'vue'
|
||||
],
|
||||
globals: {
|
||||
'ga': true, // Google Analytics
|
||||
'cordova': true,
|
||||
'__statics': true
|
||||
},
|
||||
// add your custom rules here
|
||||
'rules': {
|
||||
// allow async-await
|
||||
'generator-star-spacing': 'off',
|
||||
|
||||
// allow paren-less arrow functions
|
||||
'arrow-parens': 0,
|
||||
'one-var': 0,
|
||||
|
||||
'import/first': 0,
|
||||
'import/named': 2,
|
||||
'import/namespace': 2,
|
||||
'import/default': 2,
|
||||
'import/export': 2,
|
||||
'import/extensions': 0,
|
||||
'import/no-unresolved': 0,
|
||||
'import/no-extraneous-dependencies': 0,
|
||||
|
||||
// allow debugger during development
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
/node_modules/
|
||||
/coverage/
|
||||
/syncd/
|
||||
*.log
|
||||
/temp/
|
|
@ -0,0 +1,4 @@
|
|||
tests/
|
||||
test/
|
||||
*.test.js
|
||||
testing/
|
|
@ -0,0 +1,92 @@
|
|||
// Websocket is a native global for vanilla JS
|
||||
/* globals WebSocket:true */
|
||||
|
||||
import btc from 'better-try-catch'
|
||||
import EventEmitter from 'eventemitter3'
|
||||
import autoBind from 'auto-bind'
|
||||
|
||||
class Consumer extends EventEmitter {
|
||||
constructor (url, opts = {}) {
|
||||
super()
|
||||
this.name = opts.name || 'browser'
|
||||
this.instanceID = new Date().getTime()
|
||||
this.url = url
|
||||
this.protocol = opts.protocol
|
||||
autoBind(this)
|
||||
}
|
||||
|
||||
async connect () {
|
||||
return new Promise((resolve,reject) => {
|
||||
const socket = new WebSocket(this.url, this.protocol)
|
||||
// Connection opened
|
||||
socket.addEventListener('open', open.bind(this))
|
||||
function open () {
|
||||
this.socket = socket
|
||||
resolve(`socket open to server at : ${this.url}`)
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
reject(new Error('Socket did not connect in 5 seconds'))
|
||||
}, 5000)
|
||||
|
||||
socket.addEventListener('error', function () {
|
||||
// console.log('Web Socket error occurred')
|
||||
reject(new Error('Could not connect to socket server '))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
listen (func) {
|
||||
this.socket.addEventListener('message', handler.bind(this))
|
||||
|
||||
function handler (event) {
|
||||
let packet = {}
|
||||
if (this.socket.readyState === 1) {
|
||||
let [err, parsed] = btc(JSON.parse)(event.data)
|
||||
if (err) packet = {error: `Could not parse JSON: ${event.data}`}
|
||||
else packet = parsed
|
||||
} else {
|
||||
packet = {error: `Connection not Ready, CODE:${this.socket.readyState}`}
|
||||
}
|
||||
if (func) func(packet)
|
||||
this.emit(packet._header.id, packet)
|
||||
}
|
||||
}
|
||||
|
||||
async send (packet) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.socket.readyState !== 1) reject(new Error(`Connection not Ready, CODE:${this.socket.readyState}`))
|
||||
packet._header =
|
||||
{ id: Math.random().toString().slice(2), // need this for when multiple sends for different consumers use same packet instanceack
|
||||
sender: { name: this.name, instanceID: this.instanceID },
|
||||
url: this.url
|
||||
}
|
||||
let [err, message] = btc(JSON.stringify)(packet)
|
||||
if (err) reject(new Error(`Could not JSON stringify: ${packet}`))
|
||||
// console.log('message to send', message)
|
||||
this.socket.send(message)
|
||||
// listen for when packet comes back with unique header id
|
||||
this.once(packet._header.id, async function (reply) {
|
||||
// console.log('reply emitted', reply)
|
||||
let res = await this._packetProcess(reply)
|
||||
if (!res) { // if process was not promise returning like just logged to console
|
||||
res = reply
|
||||
console.log('consumer function was not promise returning - resolving unprocessed')
|
||||
}
|
||||
if (res.cmd ==='reply') resolve(res.response)
|
||||
else resolve(res)
|
||||
}) // end reply listener
|
||||
})
|
||||
}
|
||||
|
||||
registerPacketProcessor (func) {
|
||||
this._packetProcess = func
|
||||
}
|
||||
|
||||
async _packetProcess (packet) {
|
||||
return Promise.resolve(packet)
|
||||
}
|
||||
} // end Consumer Class
|
||||
|
||||
|
||||
export default Consumer
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"name": "@uci/websocket-client",
|
||||
"version": "0.1.2",
|
||||
"description": "JSON packet browser client over web socket",
|
||||
"main": "browser-client",
|
||||
"scripts": {
|
||||
"test": ""
|
||||
},
|
||||
"author": "David Kebler",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/uCOMmandIt/websocket-client.git"
|
||||
},
|
||||
"keywords": [
|
||||
"node.js",
|
||||
"socket",
|
||||
"websocket",
|
||||
"net",
|
||||
"JSON",
|
||||
"packet",
|
||||
"serialize",
|
||||
"TCP"
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/uCOMmandIt/websocket-client/issues"
|
||||
},
|
||||
"homepage": "https://github.com/uCOMmandIt/websocket-client#readme",
|
||||
"devDependencies": {},
|
||||
"dependencies": {
|
||||
"auto-bind": "^1.2.0",
|
||||
"eventemitter3": "^3.0.1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
# UComandIt Websocket Class for Browsers sending and receiving JSON packets
|
||||
|
||||
## What is it
|
||||
|
||||
## TL/DR;
|
||||
|
||||
## What's it good for
|
||||
|
||||
## Why Bother
|
||||
|
||||
## Getting Started
|
||||
|
||||
"babel-eslint": "^8.2.1",
|
||||
"eslint": "^4.18.2",
|
||||
"eslint-config-standard": "^11.0.0",
|
||||
"eslint-friendly-formatter": "^3.0.0",
|
||||
"eslint-loader": "^2.0.0",
|
||||
"eslint-plugin-import": "^2.9.0",
|
||||
"eslint-plugin-node": "^6.0.1",
|
||||
"eslint-plugin-promise": "^3.7.0",
|
||||
"eslint-plugin-standard": "^3.0.1"
|
Loading…
Reference in New Issue