[lib.client.ws] internal token management (stack kept while token does not match + pop stack only when valid token, else call onclose()) [lib.content-controller] added ws_connect() + ws_handler() [lib.channel-controller] now use ws_connect()

This commit is contained in:
xdrm-brackets 2018-04-04 11:19:31 +02:00
parent 49d12f935e
commit d077cdc909
3 changed files with 118 additions and 28 deletions

View File

@ -48,18 +48,8 @@ export default class ChannelController{
gs.get.room.fetch();
/* (6) Open channel websocket */
( window.csock != null ) && csock.close();
window.csock = new wscd(`wss://ws.douscord.xdrm.io/channel/${channel.id}`, { token: auth.token });
csock.onreceive = (_dat) => {
gs.get.content.ws_connect();
if( _dat.error !== 0 )
return console.log('[WS] auth failed');
csock.send({ buffer: { rid: gs.get.content.rid } });
csock.onreceive = gs.get.content.manage_update;
};
csock.bind();
/* (6) Log channel */
// console.log(`[channel.current] ${channel.link} (${channel.label})`);

View File

@ -25,19 +25,59 @@ export default class WebSocketClientDriver extends ClientDriver{
let tmp = typeof _auth !== 'object' || _auth['token'] == null || typeof _auth.token !== 'string';
this.auth = (tmp) ? { token: null } : { token: _auth.token };
/* (2) Create useful attributes */
/* (2) When token response is OK */
this.valid_token = false;
/* (3) Create useful attributes */
this.ws = null;
this.buffer = null; // useful when waiting for WebSocket to open
/* (4) Manage connection opened */
this.event.onconnected = function(){
/* (3) Manage response received */
this.event.onreceive = function(_response){
// set state from TRANSFERING to CONNECTED
// update state
this.state = ClientDriver.STATE.CONNECTED;
// call callback
this.callback.onreceive( JSON.parse(_response) );
// send token
this.ws.send(JSON.stringify({ token: this.auth.token }));
}.bind(this);
/* (5) Manage response received */
this.event.onreceive = function(_response){
/* (1) set state from TRANSFERING to CONNECTED */
this.state = ClientDriver.STATE.CONNECTED;
/* (2) Try to parse JSON */
var obj_resp = null;
try{ obj_resp = JSON.parse(_response); }catch(e){}
/* (3) JSON error -> send null */
if( obj_resp === null )
this.callback.onreceive( null );
/* (4) if TOKEN VALIDATION */
if( typeof obj_resp.error === 'number' ){
// invalid token -> tell connection closed
if( obj_resp.error !== 0 )
return this.event.onclose();
// valid token -> connected
this.callback.onconnected();
// if request(s) in stack -> pop & send them
while( this.stack.length > 0 )
this.send(this.stack.shift());
return;
}
/* (5) Else -> pass message to callback */
this.callback.onreceive(obj_resp);
}.bind(this)
@ -70,9 +110,6 @@ export default class WebSocketClientDriver extends ClientDriver{
/* (5) Bind callback.onreceive */
this.ws.onmessage = (_message_event) => this.event.onreceive(_message_event.data);
/* (6) Send authentication token */
this.send({ buffer: { token: this.auth.token } });
/* (6) Return success */
return true;
@ -89,7 +126,7 @@ export default class WebSocketClientDriver extends ClientDriver{
---------------------------------------------------------*/
send(_request){
var buffer = '{ "token": null }';
var buffer = null;
/* (0) Parent check */
if( !super.send(_request) )

View File

@ -142,10 +142,72 @@ export default class ContentController{
}
/* (9) MAIN UPDATER
/* (9) Websocket connection / reconnection
*
---------------------------------------------------------*/
manage_update(_dat){
ws_connect(){
console.warn(`new ws(/channel/${this.cid})`);
// 1. Close websocket if exists
if ( window.csock instanceof wscd )
csock.close();
// 2. Create new connection
window.csock = new wscd(`wss://ws.douscord.xdrm.io/channel/${this.cid}`, { token: auth.token });
// 3. Bind events
csock.onreceive = gs.get.content.ws_handler.bind({ event: 'receive' });
csock.onclose = gs.get.content.ws_handler.bind({ event: 'close' });
// 4. Start communication
csock.bind();
}
/* (10) Websocket connection manager
*
* @this.event<String> Event type :
* 'close' -> socket closed
* 'receive' -> received message
*
---------------------------------------------------------*/
ws_handler(_response){
console.warn('ws(', this.event, _response || '', ')');
if( this.event === null )
return;
/* (2) CLOSE event -> reconnect in 500ms
---------------------------------------------------------*/
if( this.event === 'close' )
return setTimeout(gs.get.content.ws_connect.bind(gs.get.content), 500);
/* (3) RECEIVE event
---------------------------------------------------------*/
if( this.event === 'receive' ){
/* (1) Communication error -> reconnect in 500ms */
if( typeof _response !== 'object' )
return setTimeout(gs.get.content.ws_connect.bind(gs.get.content), 500);
/* (2) If message update -> update interface model */
gs.get.content.ws_to_model(_response);
}
}
/* (11) MAIN UPDATER
*
---------------------------------------------------------*/
ws_to_model(_dat){
/* (1) Manage rooms DELETE
---------------------------------------------------------*/
@ -187,13 +249,13 @@ export default class ContentController{
let existing_index = -1;
for( let t in current_list ){
main_loop: for( let t in current_list ){
for( let r in current_list[t].list ){
if( current_list[t].list[r].id === ri ){
existing_index = r;
break;
break main_loop;
}
}
@ -272,12 +334,13 @@ export default class ContentController{
/* (4) Manage channels CREATE
---------------------------------------------------------*/
for( let c of _dat.channels.add ){
console.log(c);
gs.get.channel.dump({
gs.get.channel.dump([{
id: parseInt(c.id),
label: c.name,
link: c.link
}, true);
}], true);
}