Open mschipperheyn opened 8 years ago
Or maybe just adding a way to get the websocket object underneath webstomp-client. This will avoid to add tons of abstraction just to mimic websocket API.
I'm realizing that I need to create subscribe/unsubscribes outside of the connect callback. So, either I need to tell whether the connection is open or not or, ideally, I could just call the connect method sa often if I wanted, with the socket knowing if it was open or not and immediately returning against the callback with the already open connection or, creating a new connection.
What I do in my app is maintening a list of subscription. If I'm already connected, I call the client subscribe method, if I'm not, I store the subscription for later.
Maybe that logic can be a part of the webstomp client.
Could you share some of that code as an example. How do you know if you're already connected?
Sorry I cannot. I just store a simple boolean flag that I switch to true
once connected.
I think the websocket.readyState will provider the info
On Tue, Jul 5, 2016 at 6:22 PM Jérôme Steunou notifications@github.com wrote:
Sorry I cannot. I just store a simple boolean flag that I switch to true once connected.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/JSteunou/webstomp-client/issues/17#issuecomment-230607223, or mute the thread https://github.com/notifications/unsubscribe/AAXfv0FqCxF1kffR3VGYP1LpQ13erB_Aks5qSsssgaJpZM4I8ylu .
Kind regards,
Marc M.Schipperheyn
Then why not use stomp.ws.readyState ?
stomp client already exposes the websocket even if it's not so much documented. But using readyState
is not comfortable because you have to check its value regularly, where events like onmessage
or onerror
are triggered as it happens.
yeah, ok. the ideal would be for calling CONNECT to be indemnipotent, so subscribes and sends could always run inside the safe context of the callback.
Pull request are welcome if you wanna share your idea 😉 Le 7 juil. 2016 00:53, "Marc Schipperheyn" notifications@github.com a écrit :
yeah, ok. the ideal would be for calling CONNECT to be indemnipotent, so subscribes and sends could always run inside the safe context of the callback.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/JSteunou/webstomp-client/issues/17#issuecomment-230931813, or mute the thread https://github.com/notifications/unsubscribe/ACNyt3dBNsUj3lsMMjkgVMCSQJg6omp1ks5qTDH4gaJpZM4I8ylu .
Well, what I ended up implementing is a buffering solution, backed by a reconnecting websocket. Not sure if it's a good idea. WDYT?
const socket = class Socket{
constructor(){}
createAndConnect(sessionToken, rememberMeToken, onConnectSuccess, onConnectFailure){
this.createClient(sessionToken, rememberMeToken);
this.connect(onConnectSuccess, onConnectFailure);
}
createClient(sessionToken, authToken){
console.info(`Connecting to WebSocket: ${config.getWebsocketUrl()}`);
this.sendBuffer = [];
this.subscribeBuffer = [];
this.unsubscribeBuffer = [];
this.bufferSize = 10;
let WS = new ReconnectingWebSocket(config.getWebsocketUrl(),{},this.getCookieHeader(sessionToken, authToken), (func) => {
func();
});
WS.debug=config.debugWebsocket;
this.ws = webstomp.over(
WS,
{
debug:false
}
);
}
getCookieHeader(sessionToken, authToken){
if(sessionToken || authToken)
return {
'Cookie': ATTR_SEND_SESSIONID + '=' + sessionToken + ';' + ATTR_SEND_REMEMBERME_TOKEN + '=' + authToken
};
return {};
}
getClient(){
return this.ws? this.ws : new Error("No websocket present. Call createAndConnect first");
}
connect(onConnectSuccess, onConnectFailure){
var that = this;
this.headers = {};
this.ws.connect(this.headers, function(frame){
onConnectSuccess(frame);
that.processBuffer.bind(that)();
}, onConnectFailure);
}
disconnect(){
this.ws.disconnect();
}
send(destination, body, bufferable = true){
if(this.readyState() === WS_STATES.OPEN){
this.ws.send(destination,body, this.headers);
return;
}
if(bufferable && this.sendBuffer.length <= this.bufferSize){
this.sendBuffer.push({
destination,
body
});
}else{
throw new Error('Trying to send message on closed socket and no buffer available', destination, this.readyState());
}
}
subscribe(destination, callback, bufferable = true){
if(this.readyState() === WS_STATES.OPEN){
this.ws.subscribe(destination, (message) => {
message.ack();
callback(message);
}, this.headers);
return;
}
if(bufferable && this.subscribeBuffer.length <= this.bufferSize){
if(this.subscribeBuffer.filter((el) => el.destination === destination).length === 0)
this.subscribeBuffer.push({
destination,
callback
});
}else{
throw new Error(`Trying to subscribe on closed socket and no buffer available: ${destination}, readyState: ${this.readyState()}, buffer length: ${this.subscribeBuffer.length}`);
}
}
unsubscribe(destination, bufferable = true){
if(this.readyState() === WS_STATES.OPEN){
this.ws.unsubscribe(destination);
return;
}
if(bufferable && this.unsubscribeBuffer.length <= this.bufferSize){
if(this.unsubscribeBuffer.filter((el) => el.destination === destination).length === 0)
this.unsubscribeBuffer.push({
destination
});
}else{
throw new Error(`Trying to unsubscribe on closed socket and no buffer available: ${destination}, readyState: ${this.readyState()}, buffer length: ${this.unsubscribeBuffer.length}`);
}
}
begin(transactionId){
return this.ws.begin(transactionId);
}
commit(tx){
tx.commit();
}
abort(tx){
tx.abort();
}
sessionId(){
return this.ws.sessionId;
}
readyState(){
return this.ws.ws.readyState;
}
processBuffer(){
console.log('Processing websocket buffer', this.sendBuffer.length);
//Process unsubscribe first, in case a new subscribe came in for the to be unsubscribed endpoint
for(let action of this.unsubscribeBuffer){
this.unsubscribe(action.destination);
}
for(let action of this.subscribeBuffer){
this.subscribe(action.destination, action.callback);
}
for(let action of this.sendBuffer){
this.send(action.destination, action.body, false);
}
this.sendBuffer = [];
this.subscribeBuffer = [];
this.unsubscribeBuffer = [];
}
}
export {
socket as default
}
A PR with a clean diff is more readable
Well, this is just a suggestion. It's not a change to your code
It's useful to be able to tell whether the socket is active, opening, etc.
WebSocket exposes a readyState variable for this. It would be nice to expose it through the api