package notify import ( "b612.me/stario" "context" "net" "sync" "sync/atomic" "time" ) type ClientCommon struct { alive atomic.Value status Status byeFromServer bool conn net.Conn mu sync.Mutex msgID uint64 peerIdentity string sessionEpoch uint64 sessionOwnerState atomic.Int32 sessionRuntime atomic.Pointer[clientSessionRuntime] connectSource atomic.Pointer[clientConnectSource] queue *stario.StarQueue stopFn context.CancelFunc stopCtx context.Context parallelNum int maxReadTimeout time.Duration maxWriteTimeout time.Duration keyExchangeFn func(c Client) error linkFns map[string]func(message *Message) defaultFns func(message *Message) msgEn func([]byte, []byte) []byte msgDe func([]byte, []byte) []byte fastStreamEncode transportFastStreamEncoder fastBulkEncode transportFastBulkEncoder fastPlainEncode transportFastPlainEncoder handshakeRsaPubKey []byte SecretKey []byte noFinSyncMsgMaxKeepSeconds int lastHeartbeat int64 heartbeatPeriod time.Duration wg stario.WaitGroup netType NetType showError bool skipKeyExchange bool useHeartBeat bool sequenceDe func([]byte) (interface{}, error) sequenceEn func(interface{}) ([]byte, error) logicalSession *logicalSessionState onFileEvent func(FileEvent) fileEventObserver func(FileEvent) fileTransferCfg fileTransferConfig signalReliableCfg signalReliabilityConfig streamRuntime *streamRuntime recordRuntime *recordRuntime bulkRuntime *bulkRuntime connectionRetryState *connectionRetryState securityReadyCheck bool debugMode bool } func NewClient() Client { transport := defaultModernPSKTransportBundle() var client = ClientCommon{ maxReadTimeout: 0, maxWriteTimeout: 0, peerIdentity: newClientPeerIdentity(), sequenceEn: encode, sequenceDe: Decode, keyExchangeFn: aesRsaHello, SecretKey: nil, handshakeRsaPubKey: defaultRsaPubKey, msgEn: transport.msgEn, msgDe: transport.msgDe, fastStreamEncode: transport.fastStreamEncode, fastBulkEncode: transport.fastBulkEncode, fastPlainEncode: transport.fastPlainEncode, skipKeyExchange: true, securityReadyCheck: true, } client.alive.Store(false) client.useHeartBeat = true client.heartbeatPeriod = time.Second * 20 client.linkFns = make(map[string]func(*Message)) client.defaultFns = func(message *Message) { return } client.wg = stario.NewWaitGroup(0) client.fileTransferCfg = defaultFileTransferConfig() client.signalReliableCfg = defaultSignalReliabilityConfig() client.logicalSession = newLogicalSessionState(client.fileTransferCfg, client.signalReliableCfg) client.streamRuntime = newStreamRuntime("cstrm") client.recordRuntime = newRecordRuntime() client.bulkRuntime = newBulkRuntime("cblk") client.connectionRetryState = newConnectionRetryState() client.onFileEvent = normalizeFileEventCallback(nil) client.fileEventObserver = normalizeFileEventCallback(nil) client.stopCtx, client.stopFn = context.WithCancel(context.Background()) client.sessionRuntime.Store(newClientSessionRuntimeBase(client.stopCtx, client.stopFn)) bindClientStreamControl(&client) bindClientBulkControl(&client) client.getTransferState().setBuiltinHandler(client.builtinFileTransferHandler) return &client }