- please see windows or linux server deployment manual, deploy your raysync server.
- go to raysync admin website,create a new account.
- install SDK using npm
npm install raysync-sdk --save
- After installed raysync client,you can connect client by use
Client
instance
import { Client, ClientResponse } from 'raysync-sdk'
const client = new Client({ server_ip: 'your raysync server ip' })
client.login({ username: 'Your raysync account', password: 'Your raysync password' })
// After login successful, you can use most of the functionalities of raysync client
// Some examples:
client.on(ClientResponse.LIST, (response) => {
console.log(response)
})
client.list('/')
- If you don’t want to install and start the raysync client,you can connect raysync file server by use
FileServer
instance
import { FileServer, ServerResponse } from 'raysync-sdk'
const RAYSYNC_SERVER_IP = '127.0.0.1'
const server = new FileServer({ url: `ws://${RAYSYNC_SERVER_IP}:2480` })
server.login({ username: 'Your raysync account', password: 'Your raysync password' })
// After login successful, you can use most of the functionalities of raysync server
// Some examples:
server.on(ServerResponse.LOGIN, (response) => {
console.log(response)
server.list('/')
})
server.on(ServerResponse.LIST, (response) => {
console.log(response)
})
- Create A Client Instance
-
Client Operations
- .login(userInfo)
- .list(path [, groudId])
- .download(files [,options])
- .upload(path [,options])
- .getTaskStatus(taskId)
- .getAllTaskStatus()
- .getTaskDetailInfo(taskId)
- .mkdir(name [,path])
- .rename(oldName,newName)
- .copy(from,to [,cover])
- .move(from,to [,cover])
- .remove(files)
- .getAttributes(path)
- .getGroupList()
- .upgrade(version)
- .setLanguage(language)
- .setGroupId(groudId)
- .setSpaceId(spaceId)
- .showSyncFolder(path [,options])
- .onConnect(connected)
- .close()
- .closeFileDialog()
- Listen for changes in the transfer task state
- Create A File Server Instance
-
File Server Operations
- .login(userInfo)
- .list(path [, groudId])
- .download(files)
- .httpDownload(path)
- .upload(path)
- .mkdir(name [,path])
- .rename(oldName,newName)
- .getFileInfo(path)
- .copy(from,to [,cover])
- .move(from,to [,cover])
- .remove({path,names}[])
- .setGroupId(groudId)
- .setSpaceId(spaceId)
- .getAttributes(path)
- .close()
- Event Methods
options:
- [clientSign] {String} default is
Raysync
, Client sign value, if you use a customized raysync client, please provide it - [language] {String} client language, default is
en-US
(optional:zh-CN
,en-US
) - [protocol_version] {String} currently raysync server version
- [client_version] {String} currently client version
- [server_ip] {String} your raysync server ip, default is the host of the browser url
- [server_port] your raysync server port, default is
8090
- [proxy_ip] {String} raysync server proxy ip ,default is
null
- [proxy_port] {Number} raysync server proxy port ,default is
32001
- [server5_port] {Number} file transmission port,default is
2442
- [server5_ssl_port] {Number} file transmission encryption port,default is
2443
- [space_id] currently space id , default is
1
- [tcpEnable] {Number} default is
1
,it means enable TCP transmission ,else enable UDP transmission (optional:1
,0
) - [tcpDelay] {Number} default is
10
,Raysync supports both UDP and TCP transmissions. When Raysync client and Raysync server latency is less than tcpDelay, Raysync client automatically selects TCP for transmission; when the latency is greater than tcpDelay, Raysync client automatically selects UDP for transmission. - [autoUpdateSwitch] {Boolean} default
true
, whether to automatically upgrade the raysync client
example:
- basic usage
import { Client, ClientResponse } from 'raysync-sdk'
const client = new Client({ server_ip: 'your raysync server ip' })
- use custom options
import { Client, ClientResponse } from 'raysync-sdk'
const client = new Client({
clientSign: 'your customized client sign',
server_ip: 'your raysync service ip',
server_port: 8090,
proxy_ip: 'your raysync service ip',
proxy_port: 32001,
server5_port: 2442,
server5_ssl_port: 2443,
tcpEnable: 1,
tcpDelay: 10,
autoUpdateSwitch: true,
language: 'en-US',
recv_state: false, // Whether to listen for task state changes
})
userInfo {Object}:
- [username] {String} your raysync account.
- [password] {String} your raysync password.
- [spaceId] {Number} space id.
- [uk] {String} your custom token.
example:
- use raysync authentication service
client.login({ username: 'your raysync account', password: 'your raysync password' })
- use custom authentication service,detail see
client.login({ uk: 'your custom token' })
Get file list from the raysync client parameters:
- path {String} list path, default is
'/'
- [groudId] {Number} currently groud id, default is
0
Success will return list response info, including:
- path {String} list path
- list {Array} file list info:
- [name] {String} file name
- [size] {Number} file size
- [time] {Number} file modified time
- [file_type] {Number} file type (0:file,1:folder,2:virtual directory) example:
client.on(ClientResponse.LIST, (response) => {
console.log(response)
})
client.list('/')
parameters:
- files {Array}
- path: {String} download path
- names: {Array} file name list
- options {Object}
- regexExp?: {String} A regular expression to filter files with matching filenames for download.
- taskName?: {String} The task name for the current transfer task.
example:
client.download([{ path: '/', names: ['1.txt', '2.txt'] }])
Use the raysync client to upload files
parameters:
- path {String} upload path
- options {Object}
- regexExp?: {String} A regular expression to filter files with matching filenames for upload.
- taskName?: {String} The task name for the current transfer task.
- type?: {Number} {0:no restriction,1: folders only, 5: files only}
- isFullPath?: {Boolean} Whether to use the full path
example:
client.upload('/')
parameters:
- taskId {Number} task id.
Success will return task info response info, including:
- result {Number} response code
- message {Number} response message
- success {Boolean} this operation is successful or not
- task_list {Array} task list
- task-id {String} task id.
- task-name {String} task name.
- task-type {String} Task Type.
- upload: upload task;
- download: download task;
- task-group {String} Task grouping;
- normal:normal task;
- sync:sync task,cluster task;
- p2p:P2P transfer task;
- task-state {String} Task status;
- ready: The tasks have been created and prepared to transfer;
- start: Tasks are transferring;
- stopped: Tasks stopped transferring;
- successful:Tasks are successfully transferred;
- failed: Failed to transfer tasks;
- auth-failed: The authentication failed;
- proxy-closed: The proxy server connection failed;
- idle: The task is not triggered to transfer;
- stop-by-server: Tasks transfer is stopped by server;
- no-permission:Permission limitation;
- ip-locked: The IP address is locked;
- stop-by-peer: The P2P transfer is stopped by peer;
- failed-to-send: The P2P transfer failed to send;
- connection-failed: The P2P transfer connection failed;
- account-locked: The account is locked.
- file-max {Number} the total number of files found.
- file-pos {Number} The total number of files transferred.
- file-failed {Number} The total number of files that have failed.
- size-max {Number} The total size of the files found.
- size-pos {Number} The total size of files transferred.
- speed {Number} Transmission speed, unit: Byte/s.
- elapsed-time {Number} The total time for task execution, unit: second.
- local-path {String[]} List of local paths.
- remote-path {String[]} Server path list.
- protocol_type {String} Protocol type, udp or tcp.
example:
client.on(ClientResponse.GET_TASK_STATUS, (res) => {
console.log(res)
})
client.on(ClientResponse.UPLOAD, (response) => client.getTaskStatus(response.task_id))
client.on(ClientResponse.DOWNLOAD, (response) => client.getTaskStatus(response.task_id))
client.on(ClientResponse.SYNC, (response) => client.getTaskStatus(response.task_id))
Success will return response info, including:
- result {Number} response code
- message {Number} response message
- success {Boolean} this operation is successful or not
- task_list {Array} task list
- task-id {String} task id.
- task-name {String} task name.
- task-type {String} Task Type.
- upload: upload task;
- download: download task;
- task-group {String} Task grouping;
- normal:normal task;
- sync:sync task,cluster task;
- p2p:P2P transfer task;
- task-state {String} Task status;
- ready: The tasks have been created and prepared to transfer;
- start: Tasks are transferring;
- stopped: Tasks stopped transferring;
- successful:Tasks are successfully transferred;
- failed: Failed to transfer tasks;
- auth-failed: The authentication failed;
- proxy-closed: The proxy server connection failed;
- idle: The task is not triggered to transfer;
- stop-by-server: Tasks transfer is stopped by server;
- no-permission:Permission limitation;
- ip-locked: The IP address is locked;
- stop-by-peer: The P2P transfer is stopped by peer;
- failed-to-send: The P2P transfer failed to send;
- connection-failed: The P2P transfer connection failed;
- account-locked: The account is locked.
- file-max {Number} the total number of files found.
- file-pos {Number} The total number of files transferred.
- file-failed {Number} The total number of files that have failed.
- size-max {Number} The total size of the files found.
- size-pos {Number} The total size of files transferred.
- speed {Number} Transmission speed, unit: Byte/s.
- elapsed-time {Number} The total time for task execution, unit: second.
- local-path {String[]} List of local paths.
- remote-path {String[]} Server path list.
- protocol_type {String} Protocol type, udp or tcp.
example:
client.on(ClientResponse.GET_ALL_TASK_STATUS, (res) => {
console.log(res)
})
client.getAllTaskStatus()
Parameters:
- taskId {Number} Task id.
A successful response will return task info response info, including:
- drop_rate {Number} Packet drop rate
- elapsed_time {Number} Total task execution time, unit: seconds
- end_time {String} End time
- failed {Number} Number of failed files
- file_max {Number} Total number of found files
- file_pos {Number} Total number of transferred files
- files {String[]} File list
- is_timing_task {Boolean} Whether it is a timing task
- is_upload {Boolean} Whether it is an upload task
- local_path {String[]} List of local paths
- mss {Number} Maximum Segment Size
- protocol_type {String} Protocol type, udp or tcp
- remote_path {String[]} Server path list
- result {Number} Response code
- rtt {Number} Round Trip Time
- show_name {String} Display name
- size_max {Number} Total size of found files
- size_pos {Number} Total size of transferred files
- speed {Number} Transmission speed, unit: Byte/s
- start_time {String} Start time
- state {REQUEST_STATE} Task status, with the following meanings:
- STATE_UNKNOWN = 0
- STATE_TODO = 1 // Task is selecting upload/download path or file
- STATE_CONNECTING_PROXY = 2 // Connecting to the proxy server
- STATE_WAIT_NEXT_COMMAND = 3 // Disconnected login info, waiting for the next command to log in again
- STATE_WAIT_LOGIN_INFO = 4 // Waiting for login return before performing operations
- STATE_READY = 5 // Ready, waiting to be executed
- STATE_RECOVER = 6 // Recovering from a client crash
- STATE_STARTED = 7 // Started, running
- STATE_STOPPING = 8 // Stopping
- STATE_STOPPED = 9 // Stopped
- STATE_SUCCESSFUL = 10 // Successful
- STATE_FAILED = 11 // Failed
- STATE_AUTH_FAILED = 12 // Authentication failed, username or password error
- STATE_PROXY_CLOSED = 13 // Proxy connection disconnected or failed
- STATE_IDLE = 14 // Idle state, currently only used for timed tasks
- STATE_STOP_BY_SERVER = 15 // Server stopped transmission
- STATE_NO_PERMISSION = 16 // Insufficient permissions
- STATE_IP_IS_LOCKED = 17 // IP address is locked
- STATE_STOP_BY_PEER = 18 // Peer stopped transmission (P2P task)
- STATE_SEND_FAILED = 19 // Sending failed (P2P task)
- STATE_CONNECT_FAILED = 20 // Connection failed (P2P task)
- STATE_ACCOUNT_IS_LOCKED = 21 // Account is locked
- STATE_SERVER_STOPPED = 22 // Task server stopped
- STATE_LICENSE_EXPIRED = 23 // License expired
- STATE_DISABLED_BY_SERVER = 24 // Server disabled task
- task_id {Number} Task id
- task_name {String} Task name
- timing_type {Number} Timing type
- success {Boolean} Whether the operation is successful
Example:
client.on(ClientResponse.GET_TASK_INFO, (res) => {
console.log(res)
})
client.on(ClientResponse.UPLOAD, (response) => client.getTaskDetailInfo(response.task_id))
client.on(ClientResponse.DOWNLOAD, (response) => client.getTaskDetailInfo(response.task_id))
client.on(ClientResponse.SYNC, (response) => client.getTaskDetailInfo(response.task_id))
Create a new directory parameters:
- name {String} directory name
- [path] {String} directory path, default is
'/'
Success will return mkdir response info, including:
- result {Number} response code
- message {Number} response message
- success {Boolean} this operation is successful or not
example:
client.on(ClientResponse.MKDIR, (response) => {
console.log(response)
})
client.mkdir('test', '/')
parameters:
- oldName {String} old file name
- newName {String} new file name
Success will return rename response info, including:
- result {Number} response code
- message {Number} response message
- is_end {Boolean} this operation is completed or not
- failed_count {Number} count of failed files
- file_count {Number} count of files
example:
client.on(ClientResponse.RENAME, (response) => {
console.log(response)
})
client.rename('/old.txt', '/new.txt')
- from {Array} list of files that need to be copied
- to {Array} list of target directory
- [cover] {Boolean} default
false
, whether the file is overwritten when the target directory exists, the default is not overwritten and the value is false, or else, is the opposite.
Success will return copy response info, including:
- result {Number} response code
- message {Number} response message
- is_end {Boolean} this operation is completed or not
- failed_count {Number} count of failed files
- file_count {Number} count of files
example:
client.on(ClientResponse.COPY, (response) => {
console.log(response)
})
client.copy(['/old/1.txt', '/old/2.txt'], ['/new/1.txt', '/new/2.txt'], true)
parameters:
- from {Array} list of files that need to be moved
- to {Array} list of target directory
- [cover] {Boolean} default
false
, whether the file is overwritten when the target directory exists, the default is not overwritten and the value is false, or else, is the opposite.
Success will return move response info, including:
- result {Number} response code
- message {Number} response message
- is_end {Boolean} this operation is completed or not
- failed_count {Number} count of failed files
- file_count {Number} count of files
example:
client.on(ClientResponse.MOVE, (response) => {
console.log(response)
})
client.move(['/old/1.txt', '/old/2.txt'], ['/new/1.txt', '/new/2.txt'], true)
parameters:
- files {Object}
- path {string} file path
- names {Array} list of file name
Success will return remove response info, including:
- result {Number} response code
- message {Number} response message
- is_end {Boolean} this operation is completed or not
- failed_count {Number} count of failed files
- file_count {Number} count of files
example:
client.on(ClientResponse.REMOVE, (response) => {
console.log(response)
})
client.remove({ path: '/', names: ['1.txt', '2.txt'] })
get folder attributes
parameters:
- path {String} folder path
Success will return get attributes response info, including:
- result {Number} response code
- message {Number} response message
- is_end {Boolean} this operation is completed or not
- folder_count {Number} count of folders
- file_count {Number} count of files
- file_size {Number} file size
- write_time {Number} last modified time
example:
client.on(ClientResponse.GET_ATTRIBUTES, (response) => {
console.log(response)
})
client.getAttributes('/folder')
A successful response will return group list info, including:
- group {Array} Group list
- id {Number} Group id
- name {String} Group name
- write_time {Number} Write time
- message {String} Response message
- result {Number} Response code
- success {Boolean} Whether the operation is successful
Example:
client.getGroupList()
when the server returns a higher version than that of the local raysync client,you can upgrade your raysync client by use this method
parameters:
- version {String} version of client that need to be upgraded
example:
client.on(ClientResponse.UPDATE_CLIENT, (response) => {
console.log(response)
client.upgrade('6.0.0.8')
})
set current language of the raysync client
parameters:
- language {String} client language, default is
en-US
(optional:zh-CN
,en-US
)
example:
client.setLanguage('en-US')
set current group id parameters:
- groudId {Number} default is
0
example:
client.setGroupId(1)
set current space id parameters:
- spaceId {Number} default is
1
example:
client.setGroupId(1)
open the client sync-folder window
parameters:
- path {String} target path of the sync-folder
- options {Object}
- [forbidSyncDelete] {Boolean} default
false
, hide the delete button of sync-folder or not. - [regexExp]: {String} A regular expression to filter files with matching filenames.
- [showTaskName] {String}: The display name of the task.
- [serverPath] {String}: The server path.
- [transferTaskType] {Number}: Default is 0 (unknown). Possible values are 1 (upload), 2 (download), and 3 (sync).
- [forbidSyncDelete] {Boolean} default
example:
client.showSyncFolder('/', {
forbidSyncDelete: false,
regexExp: '',
showTaskName: '',
serverPath: '/',
transferTaskType: 1,
})
This event is used to listen whether a connection with the client has been established.
Example:
client.onConnect((connected) => {
if (connected) {
// Actions to perform when connected
}
})
close client connection, off all event listener
Close the file dialog of the client.
Parameters:
-
type
(optional): A string indicating the type of the file dialog to close. Default value is'all'
, which means close all file dialogs.
Example:
// Close all file dialogs
closeFileDialog('all')
When initializing the client, you can pass recv_state: true
to enable receiving changes in the transfer task state.
const client = new Client({
...
recv_state: true,
})
.on(ClientResponse.TASK_STATE_CHANGED, callback)
This event is used to listen for changes in the transfer task state.
this response will return task state changed response info, including:
- state {REQUEST_STATE} Task status, with the following meanings:
- STATE_UNKNOWN = 0
- STATE_TODO = 1 // Task is selecting upload/download path or file
- STATE_CONNECTING_PROXY = 2 // Connecting to the proxy server
- STATE_WAIT_NEXT_COMMAND = 3 // Disconnected login info, waiting for the next command to log in again
- STATE_WAIT_LOGIN_INFO = 4 // Waiting for login return before performing operations
- STATE_READY = 5 // Ready, waiting to be executed
- STATE_RECOVER = 6 // Recovering from a client crash
- STATE_STARTED = 7 // Started, running
- STATE_STOPPING = 8 // Stopping
- STATE_STOPPED = 9 // Stopped
- STATE_SUCCESSFUL = 10 // Successful
- STATE_FAILED = 11 // Failed
- STATE_AUTH_FAILED = 12 // Authentication failed, username or password error
- STATE_PROXY_CLOSED = 13 // Proxy connection disconnected or failed
- STATE_IDLE = 14 // Idle state, currently only used for timed tasks
- STATE_STOP_BY_SERVER = 15 // Server stopped transmission
- STATE_NO_PERMISSION = 16 // Insufficient permissions
- STATE_IP_IS_LOCKED = 17 // IP address is locked
- STATE_STOP_BY_PEER = 18 // Peer stopped transmission (P2P task)
- STATE_SEND_FAILED = 19 // Sending failed (P2P task)
- STATE_CONNECT_FAILED = 20 // Connection failed (P2P task)
- STATE_ACCOUNT_IS_LOCKED = 21 // Account is locked
- STATE_SERVER_STOPPED = 22 // Task server stopped
- STATE_LICENSE_EXPIRED = 23 // License expired
- STATE_DISABLED_BY_SERVER = 24 // Server disabled task
- task_id {Number} Task id
- success {Boolean} Whether the operation is successful
.on(ClientResponse.TRANSFER_SUCCESS, callback)
Listen for transfer success event, this response info please see .getTaskDetailInfo()
Example:
const client = new Client({
...
recv_state: true,
})
client.on(ClientResponse.TASK_STATE_CHANGED, (res) => {
console.log('TASK_STATE_CHANGED', res)
})
client.on(ClientResponse.TRANSFER_SUCCESS, (res) => {
console.log('TRANSFER_SUCCESS', res)
})
options
- url {String} raysync file server url,if you uploaded TLS certificate,please provide wss url
example:
- basic usage
import { FileServer } from 'raysync-sdk'
const RAYSYNC_SERVER_IP = '127.0.0.1'
const server = new FileServer({ url: `ws://${RAYSYNC_SERVER_IP}:2480` })
- if you uploaded an HTTPS certificate, please provide the https domain, and the port will be changed to
2481
const RAYSYNC_SERVER_IP = 'demo.raysync.cn'
const server = new FileServer({ url: `wss://${RAYSYNC_SERVER_IP}:2481` })
parameters:
userInfo {Object}:
- [username] {String} your raysync account.
- [password] {String} your raysync password.
- [spaceId] {Number} space id.
- [uk] {String} your custom token.
example:
- use raysync authentication service
server.login({ username: 'your raysync account', password: 'your raysync password' })
- use custom authentication service,detail see
server.login({ uk: 'your custom token' })
Get file list from the raysync file server parameters:
- path {String} list path, default is
'/'
Success will return list response info, including:
- result {Number} response code
- success {Boolean} this operation is success or not
- data {Array} file list info:
- [name] {String} file name
- [size] {Number} file size
- [time] {Number} file modified time
- [file_type] {Number} file type (0:file,1:folder,2:virtual directory)
example:
server.on(ServerResponse.LIST, (response) => {
console.log(response)
})
server.list('/')
download file from the raysync server, only support download file
parameters:
- path {String} file path
- [reportEvent] {Boolean} report download event to raysync server ,default is
true
- [downloadId] {Number} download id
example:
server.on(ServerResponse.ON_DOWNLOAD_START, (response) => {
console.log(response)
})
server.on(ServerResponse.ON_DOWNLOADING, (response) => {
console.log(response)
})
server.on(ServerResponse.ON_DOWNLOAD_SUCCESS, (response) => {
console.log(response)
})
server.download('/1.txt')
Download files or folders using http
parameters:
- path {Array} download path list
server.httpDownload(['/test']).then((res) => {
if (res.success) {
window.open(res.data.downloadUrl, '_blank')
}
})
upload file to the raysync server
parameters:
- options {Object}
- file {File} file object instance
- [path] upload path, default is
'/'
server.on(ServerResponse.ON_UPLOAD_START, (response) => {
console.log(response)
})
server.on(ServerResponse.ON_UPLOADING, (response) => {
console.log(response)
})
server.on(ServerResponse.ON_UPLOAD_SUCCESS, (response) => {
console.log(response)
})
const file = new File(['1'], '1.txt', {
type: 'text/plain',
})
server.upload({ file, path: '/test' })
Create a new directory parameters:
- name {String} directory name
- [path] {String} directory path, default is
'/'
Success will return mkdir response info, including:
- result {Number} response code
- success {Boolean} this operation is successful or not
example:
server.on(ServerResponse.MKDIR, (response) => {
console.log(response)
})
server.mkdir('test', '/')
- path {String} old name path
- newName {String} new file name
Success will return rename response info, including:
- result {Number} response code
- message {Number} response message
- data {Object}
- isEnd {Boolean} this operation is completed or not
- failedCount {Number} count of failed files
- successCount {Number} count of success files
example:
server.on(ServerResponse.RENAME, (response) => {
console.log(response)
})
server.rename('/test/old.txt', 'new.txt')
parameters:
- path {String} file path
Success will return file info, including:
- result {Number} response code
- message {Number} response message
- data {Object}
- fileSize {Number} File size
- writeTime {Number} Last modified time
example:
server.on(ServerResponse.GET_SERVER_FILE_INFO, (response) => {
console.log(response)
})
server.getFileInfo('/test/1.txt')
- from {String} path that need to be copied
- to {String} target path
Success will return copy response info, including:
- result {Number} response code
- message {Number} response message
- data {Object}
- isEnd {Boolean} this operation is completed or not
- failedCount {Number} count of failed files
- successCount {Number} count of success files
example:
server.on(ServerResponse.MOVE_OR_COPY, (response) => {
console.log(response)
})
server.copy('/a/1.txt', '/a/b/1.txt')
- from {String} path that need to be moved
- to {String} target path
Success will return move response info, including:
- result {Number} response code
- message {Number} response message
- data {Object}
- isEnd {Boolean} this operation is completed or not
- failedCount {Number} count of failed files
- successCount {Number} count of success files
example:
server.on(ServerResponse.MOVE_OR_COPY, (response) => {
console.log(response)
})
server.move('/a/1.txt', '/a/b/1.txt')
remove a single file parameters: path {String} file path
Success will return remove response info, including:
- result {Number} response code
- message {Number} response message
- data {Object}
- isEnd {Boolean} this operation is completed or not
- failedCount {Number} count of failed files
- successCount {Number} count of success files
example:
server.on(ServerResponse.REMOVE, (response) => {
console.log(response)
})
server.remove('/1.txt')
set current group id parameters:
- groudId {Number} default is
0
example:
server.setGroupId(1)
set current space id parameters:
- spaceId {Number} default is
1
example:
server.setGroupId(1)
parameters:
- path {String} folder path
Success will return get attributes response info, including:
- result {Number} response code
- message {Number} response message
- is_end {Boolean} this operation is completed or not
- folder_count {Number} count of folders
- file_count {Number} count of files
- file_size {Number} file size
- write_time {Number} last modified time
example:
server.on(ServerResponse.GET_ATTRIBUTES, (response) => {
console.log(response)
})
server.getAttributes('/folder')
example:
const handler = (res) => console.log(res)
client.on(ClientResponse.LOGIN, handler)
client.once(ClientResponse.LOGIN, handler)
client.off(ClientResponse.LOGIN, handler)