vpn.email.client
Version:
Vpn.Email client IMAP core
220 lines (179 loc) • 6.31 kB
text/typescript
/*!
* Copyright 2017 Vpn.Email network security technology Canada Inc. All Rights Reserved.
*
* Vpn.Email network technolog Canada Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as Async from 'async'
import imapConnect from './class_imapConnect'
import * as Stream from 'stream'
import * as Compress from './compress'
import * as execImap from './execImap'
export default class imapCluster {
private mainImapPool: execImap.VE_IimapPool [] = []
private subImapPool:execImap.VE_IimapPool [] = []
private masterImap: imapConnect[] = []
private dataPool: ISaveDataPool[] = []
private endcall = false
private mainImapPoint = 0
private aliasImapPoint = 0
private maindataPool: Buffer[] = []
private CallBackPool: Map < string, () => void > = new Map ()
private count = 0
private findIdleImap () {
for ( let i = 0; i < this.subImapPool.length; i ++ ) {
const n = this.subImapPool [ this.aliasImapPoint ]
if ( ++ this.aliasImapPoint === this.subImapPool.length )
this.aliasImapPoint = 0
if ( !n.execImap.saveBusy && n.execImap.ready )
return n.execImap
}
return null
}
private findMainImap ( CallBack ) {
for ( let i = 0; i < this.mainImapPool.length; i ++ ) {
const n = this.mainImapPool [ this.mainImapPoint ]
if ( ++ this.mainImapPoint === this.mainImapPool.length )
this.mainImapPoint = 0
if ( ! n.execImap.saveBusy && n.execImap.ready ) {
return CallBack ( n.execImap )
}
}
for ( let i = 0; i < this.subImapPool.length; i ++ ) {
const n = this.subImapPool [ this.aliasImapPoint ]
if ( ++ this.aliasImapPoint === this.subImapPool.length )
this.aliasImapPoint = 0
if ( ! n.execImap.saveBusy && n.execImap.ready ) {
return CallBack ( n.execImap )
}
}
return CallBack ()
}
private saveMainData = ( n: execImap.execImap ) => {
if ( !this.maindataPool.length )
return
const data = this.maindataPool
this.maindataPool = []
console.log ('')
console.log ('save main Data data.length = ', data.length )
data.forEach ( nn => {
const uu = Compress.openPacket ( nn )
console.log (`[${ uu.uuid }] ==> ${ uu.buffer.length }`)
})
console.log ('')
Async.waterfall ([
next => Compress.encrypt ( new Buffer (JSON.stringify( data ), 'utf8'), this.password, next ),
( _data, next ) => n.sendMessage ( _data, next )
], err => {
if ( err ) {
this.maindataPool = data.concat ( this.maindataPool )
return this.pushMainData ( null )
}
return this.saveMainData ( n )
})
}
private packageData ( data: ISaveDataPool ) {
if ( data.noExcrypt ) {
return Compress.encrypt ( data.buffer, this.password, ( err, _data ) => {
return Compress.packetBuffer ( 0, data.index, data.uuid, _data )
})
}
return Compress.packetBuffer ( 5, data.index, data.uuid, data.buffer )
}
constructor ( private imapUsers: IinputData[], private password: string, private isServer: boolean, private _newMail: ( data ) => void, private doFock: boolean, private endCall ) {
Async.each ( imapUsers, ( n, down ) => {
this.masterImap.push ( new imapConnect ( n, ( data ) => { this._newMail ( data )},
this.subImapPool, () => {
console.log ( 'ImapCluster =====================> reConnect main ()!' )
this.pushMainData ( null )
}, () => {
console.log ( 'ImapCluster =====================> reConnect sub ()!' )
this.pushData ( null )
},
this.mainImapPool, password,
isServer, this.CallBackPool, doFock, () => {
if ( !this.endcall ) {
this.endcall = true
return this.endCall ()
}
}))
down()
})
}
public pushMainData ( buffer: Buffer ) {
if ( buffer && buffer.length ) {
const data = Compress.openPacket ( buffer )
console.log ( `===> uuid[${ data.uuid }],serial[${ data.serial }], buffer[${ data.buffer.length }]` )
this.maindataPool.unshift ( buffer )
}
this.findMainImap (( n: execImap.execImap ) => {
if ( !n ) {
return console.log ('have no n to save mainData', this.maindataPool.length, this.mainImapPool.length)
}
this.saveMainData ( n )
})
}
private saveData ( n: execImap.execImap ) {
if ( !n )
return console.log ( 'saveData have not n: execImap.execImap', this.dataPool.length, this.subImapPool.length )
if ( ! this.dataPool.length )
return
const data = this.dataPool
this.dataPool = []
const _data = []
console.log ('')
console.log ('saveData data.length = ', data.length )
data.forEach ( nn => {
console.log (`[${ nn.uuid }]==>${ nn.buffer.length }`)
_data.push ( this.packageData ( nn ))
})
console.log ('')
Async.waterfall ([
next => Compress.encrypt ( new Buffer (JSON.stringify( data ), 'utf8'), this.password, next ),
( _Data, next ) => {
n.sendMessage ( _Data, err => {
if ( err ) {
console.log ( 'n.sendMessage save ERROR', ``,err.message )
this.dataPool = data.concat ( this.dataPool )
return this.pushData ( null )
}
return this.saveData ( n )
})
}])
}
public pushData ( data: ISaveDataPool ) {
if ( data )
this.dataPool.unshift ( data )
return this.saveData ( this.findIdleImap ())
}
public getDataUuid ( uuid ) {
const index = this.dataPool.findIndex ( n => {
return n.uuid === uuid
})
if ( index < 0 )
return null
const data = this.dataPool[index]
this.dataPool.splice ( index, 1 )
return data
}
public destroyAllDataUuid ( uuid ) {
const index = this.dataPool.findIndex ( n => {
return n.uuid === uuid
})
if ( index < 0 )
return
//console.log ( '-----------------destroyAllDataUuid: ', uuid )
this.dataPool.splice ( index, 1 )
this.destroyAllDataUuid ( uuid )
}
}