lukeed / sockette Goto Github PK
View Code? Open in Web Editor NEWThe cutest little WebSocket wrapper! π§¦
License: MIT License
The cutest little WebSocket wrapper! π§¦
License: MIT License
Since the first call to window.setTimeout
or window.setInterval
is returning handle with ID 1
calling Sockette.close
would unexpectedly clear that timeout, because timer=1
is still a valid handle ID.
Awesome Library.
I was taking a look at the re-connection handler and noticed it just takes a static delay before attempting to reconnect.
I usually like to use some form of re-connection strategy to control how a re-connection occurs for example an Exponential Back-off.
Would this be a suitable feature addition?
To keep the module size down the constructor could take a function:
new Sockette(..., {
reconnection: (attempts, maxAttempts) => Number
});
Am I misunderstanding this method or is it not working?
socket = new Sockette(action.url, {
timeout: 5000,
maxAttempts: 2,
onopen: onOpen(store),
onclose: onClose(store),
onmessage: onMessage(store),
onmaximum: onMaximum(store),
onreconnect: onReconnect(store),
onerror: noop,
});
I have this snippet setup. Everything works as expected. When the WS server is down, Sockette tries to connect twice, before giving up, however the onmaximum
callback is never triggered.
Since the underlying web socket is no longer returned, we lost access to some properties. While we can easily track the readyState using the different lifecycle methods, it would be nice to have a quick getter.
self.state= () => {
return ws.readyState;
};
If the close frame contains no status code (payload length == 0), the close code is 1005. In this case sockette should not reconnect.
Hey there.
First of all, thanks for a great work on this library.
So I created a library to bind Sockette to React and Preact at the same time. I wanted to reduce the hassle of switching the component from the two library. the idea just lands in creating a component factory.
You can check it out here.
I was wondering, is there any chance we can merge it with your version of preact-sockette?
This way both React and Preact users can enjoy using this component. and Yes, I am aware of compat libraries :) I just think creating a factory for components is a better way since it can also be used in other alternatives such as Inferno too.
and probably a good idea that all the components that we create for these libraries, be written as factories.
I was wondering on ws.onclose, why on those specific code numbers we donβt want to try to reconnect. Codes 1003, 1001, and 1005. Why not have it try to always reconnect if it loses a connection?
Arrow functions don't create a binding, and a quick look over the code doesn't show a single instance where the difference in bindings would matter. Every instance of this
can be replaced with self
.
The sock in the Sockette logo appears to be shiny[1], which could make it unintentionally arousing to rubber fetishists[2].
Hi, Will sockette increase the typescript type declaration file?
i seen this on twitter and looked very promising. So did a quick look and dont see support for verifyClient; use this to validate the ws has the json web token (JWT). see documentation at:
https://github.com/websockets/ws/blob/master/doc/ws.md
Hello,
The documentation for onerror
says "Important: If the event.code is ECONNREFUSED, an automatic reconnect attempt will be queued."
However, when doing onerror: e => console.log('Error:', e)
, it looks like e.code
doesn't exist.
I built up the WebSocket server with AWS API Gateway
.
and, I am connecting this with AWS Lambda
.
It works well when I connect, but when I disconnect, it doesn't work well.
My React Client Code
import React from 'react';
function socketHandler(uid){
const wss = new Sockette(`wss://MY_API_GATEWAY_URL.execute-api.ap-northeast-2.amazonaws.com/dev?groupId=GROUP_ID&uid=${uid}`, {
timeout: 1000,
maxAttempts: 10,
onopen: (e: any) => { console.log(e); console.log('Websocket is connected') },
onmessage: (e: any) => {
console.log(e.data);
},
onclose: (e: any) => { console.log(e); console.log('Websocket is disconnected'); }
});
return wss;
}
const SocketForm = (props) => {
const [socket, setSocket] = React.useState(null);
React.useEffect(()=> {
setSocket(socketHandler(`MY_UID`);
}, []);
const socketDisconnect = () => {
socket.close();
}
return (
<div>
<button onClick={socketDisconnect}>Disconnect</button>
</div>
)
}
My Lambda Code
/* it works well when I connect. */
export const socketHandler = async (evt) => {
const {groupId, uid} = evt.queryStringParameters; // When I disconnect it occurs ERROR.
/* Skip Saving connectionId */
return { statusCode: 200, body: JSON.stringify({}) };
};
I'd like to use WebSocket URL with queryParameters
even I disconnect.
If I missed something, please reply me.
I just tested v2.0.5 and unfortunately the issue is still there. This is my scenario:
After a while WS connections A and B are reopened. They are initially closed, but re-opened.
If I call ws.close while there's a reconnection setTimeout pending, sockette still tries to reconnect after the timer finishes. I don't think this is the expected behavior, especially when you try to close the websocket after a connection failure, as it keeps trying to reconnect and failing.
First time I've used sockets in a while...
I'm building a simple react voting example that allows a room of people to click as many times and as fast as they want on one of 6 choices and that will cast their vote.
This definitely seems like an issue with how fast everything can process each vote.
However, I'm not sure where to start?
This is the bulk of the code:
const onVote = vote => {
console.log({ vote, ws });
ws.json({
action: 'sendMessage',
data: JSON.stringify(vote)
});
};
const onMessageReceied = ({ data }) => {
console.log({ data });
const voteData = JSON.parse(data);
console.log({ onMessageReceied: voteData });
setBallotsList({ ...ballotsList, ...voteData });
};
useEffect(() => {
console.log({ ballotsList });
ws = new Sockette(config.site.api, {
timeout: 5e3,
maxAttempts: 1,
onopen: e => console.log('connected:', e),
onmessage: e => onMessageReceied(e),
onreconnect: e => console.log('Reconnecting...', e),
onmaximum: e => console.log('Stop Attempting!', e),
onclose: e => console.log('Closed!', e),
onerror: e => console.log('Error:', e)
});
return function cleanup() {
ws && ws.close();
ws = null;
};
}, [ballotsList]);
Hi there
I would like hear if this project is still maintained?
Thank you for making this package! It's great.
This is a feature request.
AWS API Gateway allows only a maximum size of 128kb of data to be sent across 4 x 32kb frames when using Websockets:
https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html
I would love it if this package allowed me to specify the maximum frame size somewhere and then it would automatically split up messages and re-combine them on the other side to overcome this.
Hi! I loved your lib right away!
I have a question, is there a way to tell if max attempts are reached and it will no longer reconnect? Something like ws.isExhausted
or ws.doneTrying
? We have HTTP failover in our apps and I would like to only failover after Sockette is exhausted.
If there isn't such a flag I'd be glad to PR.
Cheers
Hi, I saw from your README that WebSocket
object is available in each EventListener
, but is there a way to access it outside of event listeners? Would like to get the state of WebSocket to determine whether to stop an interval to ping the websocket server, thanks.
Hi pal,
How do you intentional close the websocket without reconnection execution, its necessary to pass event code to close method?
when manually invoke close method I think that the reconnection should not be done
ws.close()
thanks
At the moment PR #48 is not included in the current NPM version.
Hello there,
It looks like the latest release on npm is not including your typings for typescript.
Do you mind publishing a new minor version with those great changes?
Thank you!
I don't see any option to add custom headers to the WS connection. I know this may not be used for browser based implementations of websocket connections, but many server-side client libs need to provide an Authorization header to connect to a websocket. Is this something you could see using on this project? Thanks!
Hi pal,
it will be great to have heartbeat mechanism (optional) like ping / pong to check the connection availability, what do you think?
Of course we need special pong message from server (this is why feature must be optional).
Thanks !!!
Hi, awesome lib.
Is there any way that we can disable reconnect programmatically ?
For example, we init a sockette instance with maxAttempts by default(always enable recconnecting), after a several times of connection failure, I would like to provide a way to disable the further reconnecting manually. Thanks.
In my project, I want to shutdown the connection when I leave out. However, no matter the code I passed to close method, it failed, e.g. ," ws.close(1000, 'out')". Why?
Right now in order to change websocket url you have to create a new instance of Sockette. This an issue for us because our url includes authorization token which expires after some time and when Sockette tries to reconnect it tries to reconnect using an expired token.
Here are a couple of possible solutions to this issue:
getUrl
config which can be set to a function which either returns a string
directly or a Promise<string>
. Sockette would use this function every time it tries to automatically establish websocket connection.setUrl()
method on the Sockette class and ability to set onreconnect
config to a function which returns a Promise
. Sockette would wait for onreconnect
promise to finish before it would try to reestablish connection.@lukeed what do you think about it? Do you have any better suggestions?
On readme: "Upon creation, the WebSocket is returned directly, exposing the native close and send methods."
But version 2 changed return $.open();
(which returns the ws) to return self;
and the websocket is not accessible.
Hi, i have a problem when testing my component using mocha & chai, it says:
ReferenceError: WebSocket is not defined
at module.exports.r.open (/Users/bcw-001/dev/sofia_fe_react/node_modules/sockette/src/index.js:25:32)
at new module.exports (/Users/bcw-001/dev/sofia_fe_react/node_modules/sockette/src/index.js:48:7)
i use mock-websocket. anyone know what did i miss?
Basically the opposite of #23, onmaximum
triggers immediately. I have my Sockette instances configured to attempt to connect 5 times before giving up. If my backend server is not running, it attempts one connection, fails, and gives up. I can confirm that if the server is running and it successfully connects, then the server is shut down, it will attempt one reconnect before failing and giving up again.
After inspecting the events, I'm not getting a 1000 or 1005. In fact, the only event code I'm able to actually see is 1006, which should trigger a reconnect according to the docs. What's happening is a connection attempt is made, fails, then calls onerror and onclose (which is expected), then straight to onmaximum.
Here's the code currently (with logging stuff removed):
this._ws = new Sockette(url, {
timeout: 60000,
maxAttempts: 5,
onopen: () => {
console.log('[Chat] Connection successful.')
this.setState({ connected: true }, () => {
const payload = {
channel: 'chat-login',
payload: { from: this.state.myself }
}
this._ws.json(payload)
})
},
onclose: () => console.log('[Chat] Connection closed.'),
onmessage: ({ data }) => this._onMessage(JSON.parse(data)),
onmaximum: () => console.error('[Chat] Too many connection attempts. Giving up.'),
onreconnect: () => console.log('[Chat] Reconnecting...'),
onerror: () => {
console.error('[Chat] Disconnected.')
this.setState({ connected: false })
}
})
Shouldn't it attempt to connect four more times, or have I misread or missed something in the documentation?
Is it possible to use sockette with express application? Can you provide some little example about that?
Thanks
When I run our build with v2.0.2 or v2.0.3 I get the following error message. However, if I run with v2.0.1 our project builds without error.
ERROR in 13.ce2f3dc9b0373574d554.chunk.js from UglifyJs
Unexpected token: operator (>) [/work/node_modules/sockette/dist/sockette.js:30,0][13.ce2f3dc9b0373574d554.chunk.js:2646,32]
Child html-webpack-plugin for "index.html":
1 asset
I have tried updating to the latest html-webpack-plugin
in case that was an issue, but it doesn't seem to be.
hi,
websocket sometimes is a mystery to me.
Could you please explain why you don't reconnect on error 1005,
and why you reconnect on ECONNREFUSED.
thanks in advance
I've created a new Angular project using the Angular CLI and have installed and attempted to import Sockette into my project (an empty Angular project.)
I am getting the below error when trying to import/require Sockette.
TypeError: "Sockette is not a constructor"
import
gets me the above error:import {Component} from '@angular/core';
import {environment} from '../environments/environment';
import * as Sockette from 'sockette';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
constructor() {
const socket = new Sockette(environment.websocket_server);
}
}
require
gets me the same error above:import {Component} from '@angular/core';
import {environment} from '../environments/environment';
const Sockette = require('sockette');
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
constructor() {
const socket = new Sockette(environment.websocket_server);
}
}
When I console.log
the Sockette object, I get the following:
import {Component} from '@angular/core';
import {environment} from '../environments/environment';
const Sockette = require('sockette');
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
constructor() {
console.log(Sockette);
const socket = new Sockette(environment.websocket_server);
}
}
Object { default: default(), β¦ }
Which lead me to try the following (which works!)
import {Component} from '@angular/core';
import {environment} from '../environments/environment';
const Sockette = require('sockette');
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
constructor() {
const socket = new Sockette.default(environment.websocket_server);
}
}
I'm left assuming this is due to the way Sockette is being exported... any thoughts?
Would a developer be able to specify the binaryType
attribute of the websocket?.. such as what's noted in the MDN docs?
Could this be an option or does the developer have access to the native Websocket via sockette?
// Create WebSocket connection.
const socket = new WebSocket('ws://localhost:8080');
socket.binaryType = 'arraybuffer';
In an application I'm working on I'd like to check that the socket has flushed data. This can be done using socket.bufferedAmount
according to this SO post
Could this library support a function to check this, or simply expose the underlying socket object for these use cases, e.g:
const ws = new Sockette('ws://localhost:3000', {
timeout: 5e3,
maxAttempts: 10,
onopen: e => console.log('Connected!', e),
onmessage: e => console.log('Received:', e),
onreconnect: e => console.log('Reconnecting...', e),
onmaximum: e => console.log('Stop Attempting!', e),
onclose: e => console.log('Closed!', e),
onerror: e => console.log('Error:', e)
});
// access underlying socket
ws.socket.bufferedAmount
hi, i use json or send on my project, and sometimes i will get an error
Failed to execute 'send' on 'WebSocket': Still in CONNECTING state
i already using handler for when onopen i changed the status which enabling my button can be used and i still sometimes get the same error
so here my suggestion, instead using send(string) or json(data), i think we should be able to add one more param for error lik send(string, errorHandler) or json(data, errorHandler)
I'm just learning React and using Sockette as one of the first implementations. I managed to get the websocket connection working, however I can't see how I can update a given React State with the received message (onmessage). Sending is working fine and receiving as well, just can't update a given state from outside of the React Component. Below the code:
//Websockets in test.js
import Sockette from 'sockette';
const ws_scheme = window.location.protocol == "https:" ? "wss" : "ws";
const ws_path = ws_scheme + '://' + window.location.host + '/ramascene/';
const ws = new Sockette(ws_path, {
timeout: 5e3,
maxAttempts: 10,
onopen: e => console.log('Connected!', e),
onmessage: e => console.log('received!', e),
onreconnect: e => console.log('Reconnecting...', e),
onmaximum: e => console.log('Stop Attempting!', e),
onclose: e => console.log('Closed!', e),
onerror: e => console.log('Error:', e)
})
.....
//parent component Board also in test.js
class Board extends React.Component<Props, State>{
handleAjax: Function;
handleWSSend: Function;
//#code ID9
//default state of variables
constructor(props) {
super(props);
this.handleAjax = this.handleAjax.bind(this)
//default state
this.state = {test: "bla"}
}
//handle the websocket transmission for starting a task
handleWSSend(){
console.log("analyse fired")
ws.send(JSON.stringify({'vizType': "GeoMap",'dimType': "Consumption",
'action': "start_calc"
}));
}
}``
I built my app starting with the convenient create-react-app. It comes with Jest built in for testing. However, I can't run any tests because of the following error:
ReferenceError: WebSocket is not defined
at Object.<anonymous>.module.exports.r.open (node_modules/sockette/dist/sockette.js:1:508)
at new Object.<anonymous>.module.exports (node_modules/sockette/dist/sockette.js:1:745)
at new NTWebSocket (src/server.js:14:15)
at Object.<anonymous> (src/index.js:22:17)
at Object.<anonymous> (src/test/App.test.js:21:14)
Can I modify the timeout
in onreconnect()
-- for example, to increase the delay after 10 attempts to reconnect? I do not see the timeout
variable on the event.target
.
Hi there, sorry if my issue is silly, I'm still amateur in websockets handling. I'm facing a problem where I couldn't disconnect properly using sockette when the network is offline. I'm currently using sockette to connect with my Websocket API using AWS API Gateway, everything seems fine except when I realized that the connections created by the gateway isn't always being disconnected thus leaving many dead connection records in my DynamoDB. This is how I replicate the issue:
I'm wondering do Sockette handles such situation, at least have a callback when offline connection is detected? If it's already available, how can I modify my code to cater for that? This is my code in React:
useEffect(
() => {
if (isProduction) {
webSocket = new Sockette(webSocketUrlFor(userId), {
timeout: 5e3,
onopen: e => console.log('Connected', e),
onmessage: onReceivedMessage,
onreconnect: () => console.log('Reconnecting...'),
onmaximum: e => console.log('Stop Attempting!', e),
onclose: e => {
console.log('Closed connection. Reconnecting...', e);
webSocket.reconnect();
},
onerror: e => console.log('Error:', e)
});
return () => {
webSocket.close();
};
}
},
[userId]
);
How to get error code while getting the error from the socket connection in onerror()?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.