@heroiclabs/nakama-js
Advanced tools
Comparing version 2.5.3 to 2.6.0
@@ -412,3 +412,3 @@ /** | ||
/** A socket created with the client's configuration. */ | ||
createSocket(useSSL?: boolean, verbose?: boolean, adapter?: WebSocketAdapter): Socket; | ||
createSocket(useSSL?: boolean, verbose?: boolean, adapter?: WebSocketAdapter, sendTimeoutMs?: number): Socket; | ||
/** Delete one or more users by ID or username. */ | ||
@@ -415,0 +415,0 @@ deleteFriends(session: Session, ids?: Array<string>, usernames?: Array<string>): Promise<boolean>; |
@@ -461,2 +461,5 @@ /** | ||
} | ||
/** Application-level heartbeat ping. */ | ||
interface Ping { | ||
} | ||
/** A snapshot of statuses for some set of users. */ | ||
@@ -592,2 +595,4 @@ export interface Status { | ||
onchannelpresence: (channelPresence: ChannelPresenceEvent) => void; | ||
setHeartbeatTimeoutMs(ms: number): void; | ||
getHeartbeatTimeoutMs(): number; | ||
} | ||
@@ -608,8 +613,15 @@ /** Reports an error received from a socket message. */ | ||
readonly adapter: WebSocketAdapter; | ||
readonly sendTimeoutMs: number; | ||
static readonly DefaultHeartbeatTimeoutMs = 10000; | ||
static readonly DefaultSendTimeoutMs = 10000; | ||
static readonly DefaultConnectTimeoutMs = 30000; | ||
private readonly cIds; | ||
private nextCid; | ||
constructor(host: string, port: string, useSSL?: boolean, verbose?: boolean, adapter?: WebSocketAdapter); | ||
private _heartbeatTimeoutMs; | ||
constructor(host: string, port: string, useSSL?: boolean, verbose?: boolean, adapter?: WebSocketAdapter, sendTimeoutMs?: number); | ||
generatecid(): string; | ||
connect(session: Session, createStatus?: boolean): Promise<Session>; | ||
connect(session: Session, createStatus?: boolean, connectTimeoutMs?: number): Promise<Session>; | ||
disconnect(fireDisconnectEvent?: boolean): void; | ||
setHeartbeatTimeoutMs(ms: number): void; | ||
getHeartbeatTimeoutMs(): number; | ||
ondisconnect(evt: Event): void; | ||
@@ -625,3 +637,3 @@ onerror(evt: Event): void; | ||
onparty(party: Party): void; | ||
onpartyclose(): void; | ||
onpartyclose(close: PartyClose): void; | ||
onpartyjoinrequest(partyJoinRequest: PartyJoinRequest): void; | ||
@@ -635,3 +647,3 @@ onpartydata(partyData: PartyData): void; | ||
onstreamdata(streamData: StreamData): void; | ||
send(message: ChannelJoin | ChannelLeave | ChannelMessageSend | ChannelMessageUpdate | ChannelMessageRemove | CreateMatch | JoinMatch | LeaveMatch | MatchDataSend | MatchmakerAdd | MatchmakerRemove | PartyAccept | PartyClose | PartyCreate | PartyDataSend | PartyJoin | PartyJoinRequestList | PartyLeave | PartyMatchmakerAdd | PartyMatchmakerRemove | PartyPromote | PartyRemove | Rpc | StatusFollow | StatusUnfollow | StatusUpdate): Promise<any>; | ||
send(message: ChannelJoin | ChannelLeave | ChannelMessageSend | ChannelMessageUpdate | ChannelMessageRemove | CreateMatch | JoinMatch | LeaveMatch | MatchDataSend | MatchmakerAdd | MatchmakerRemove | PartyAccept | PartyClose | PartyCreate | PartyDataSend | PartyJoin | PartyJoinRequestList | PartyLeave | PartyMatchmakerAdd | PartyMatchmakerRemove | PartyPromote | PartyRemove | Rpc | StatusFollow | StatusUnfollow | StatusUpdate | Ping, sendTimeout?: number): Promise<any>; | ||
acceptPartyMember(party_id: string, presence: Presence): Promise<void>; | ||
@@ -663,3 +675,4 @@ addMatchmaker(query: string, min_count: number, max_count: number, string_properties?: Record<string, string>, numeric_properties?: Record<string, number>): Promise<MatchmakerTicket>; | ||
writeChatMessage(channel_id: string, content: any): Promise<ChannelMessageAck>; | ||
private pingPong; | ||
} | ||
export {}; |
@@ -36,3 +36,3 @@ /** | ||
onOpen: SocketOpenHandler | null; | ||
readonly isConnected: boolean; | ||
isOpen(): boolean; | ||
close(): void; | ||
@@ -71,3 +71,2 @@ connect(scheme: string, host: string, port: string, createStatus: boolean, token: string): void; | ||
export declare class WebSocketAdapterText implements WebSocketAdapter { | ||
private _isConnected; | ||
private _socket?; | ||
@@ -82,3 +81,3 @@ get onClose(): SocketCloseHandler | null; | ||
set onOpen(value: SocketOpenHandler | null); | ||
get isConnected(): boolean; | ||
isOpen(): boolean; | ||
connect(scheme: string, host: string, port: string, createStatus: boolean, token: string): void; | ||
@@ -85,0 +84,0 @@ close(): void; |
{ | ||
"name": "@heroiclabs/nakama-js", | ||
"version": "2.5.3", | ||
"version": "2.6.0", | ||
"scripts": { | ||
@@ -5,0 +5,0 @@ "build": "npx tsc && npx rollup -c --bundleConfigAsCjs && node build.mjs" |
@@ -165,7 +165,8 @@ Nakama JavaScript client | ||
To build from source, install dependencies and build the `nakama-js` and `nakama-js-protobuf` subrepositories: | ||
To build from source, first install all workspace dependencies from the repository root with `npm install`. | ||
Then to build a specific workspace, pass the `--workspace` flag to your build command, for example: | ||
```shell | ||
npm install --workspace=@heroiclabs/nakama-js && npm run build --workspace=@heroiclabs/nakama-js | ||
npm install --workspace=@heroiclabs/nakama-js-protobuf && npm run build --workspace=@heroiclabs/nakama-js-protobuf | ||
npm run build --workspace=@heroiclabs/nakama-js | ||
``` | ||
@@ -172,0 +173,0 @@ |
@@ -511,2 +511,7 @@ /** | ||
/** Application-level heartbeat ping. */ | ||
interface Ping { | ||
} | ||
/** A snapshot of statuses for some set of users. */ | ||
@@ -691,2 +696,8 @@ export interface Status { | ||
onchannelpresence: (channelPresence: ChannelPresenceEvent) => void; | ||
/* Set the heartbeat timeout used by the socket to detect if it has lost connectivity to the server. */ | ||
setHeartbeatTimeoutMs(ms : number) : void; | ||
/* Get the heartbeat timeout used by the socket to detect if it has lost connectivity to the server. */ | ||
getHeartbeatTimeoutMs() : number; | ||
} | ||
@@ -704,4 +715,9 @@ | ||
export class DefaultSocket implements Socket { | ||
public static readonly DefaultHeartbeatTimeoutMs = 10000; | ||
public static readonly DefaultSendTimeoutMs = 10000; | ||
public static readonly DefaultConnectTimeoutMs = 30000; | ||
private readonly cIds: { [key: string]: PromiseExecutor }; | ||
private nextCid: number; | ||
private _heartbeatTimeoutMs: number; | ||
@@ -713,6 +729,8 @@ constructor( | ||
public verbose: boolean = false, | ||
readonly adapter : WebSocketAdapter = new WebSocketAdapterText() | ||
readonly adapter : WebSocketAdapter = new WebSocketAdapterText(), | ||
readonly sendTimeoutMs : number = DefaultSocket.DefaultSendTimeoutMs | ||
) { | ||
this.cIds = {}; | ||
this.nextCid = 1; | ||
this._heartbeatTimeoutMs = DefaultSocket.DefaultHeartbeatTimeoutMs; | ||
} | ||
@@ -726,4 +744,4 @@ | ||
connect(session: Session, createStatus: boolean = false): Promise<Session> { | ||
if (this.adapter.isConnected) { | ||
connect(session: Session, createStatus: boolean = false, connectTimeoutMs: number = DefaultSocket.DefaultConnectTimeoutMs): Promise<Session> { | ||
if (this.adapter.isOpen()) { | ||
return Promise.resolve(session); | ||
@@ -778,4 +796,4 @@ } | ||
this.onpartydata(<PartyData>message.party_data); | ||
} else if (message.on_party_close) { | ||
this.onpartyclose(); | ||
} else if (message.party_close) { | ||
this.onpartyclose(<PartyClose>message.party_close); | ||
} else if (message.party_join_request) { | ||
@@ -819,2 +837,4 @@ this.onpartyjoinrequest(message.party_join_request); | ||
} | ||
this.pingPong(); | ||
resolve(session); | ||
@@ -826,2 +846,8 @@ } | ||
} | ||
setTimeout(() => { | ||
// if promise has resolved by now, the reject() is a no-op | ||
reject("The socket timed out when trying to connect."); | ||
}, connectTimeoutMs); | ||
}); | ||
@@ -831,3 +857,3 @@ } | ||
disconnect(fireDisconnectEvent: boolean = true) { | ||
if (this.adapter.isConnected) { | ||
if (this.adapter.isOpen()) { | ||
this.adapter.close(); | ||
@@ -840,2 +866,10 @@ } | ||
setHeartbeatTimeoutMs(ms : number) { | ||
this._heartbeatTimeoutMs = ms; | ||
} | ||
getHeartbeatTimeoutMs() : number { | ||
return this._heartbeatTimeoutMs; | ||
} | ||
ondisconnect(evt: Event) { | ||
@@ -901,5 +935,5 @@ if (this.verbose && window && window.console) { | ||
onpartyclose() { | ||
onpartyclose(close: PartyClose) { | ||
if (this.verbose && window && window.console) { | ||
console.log("Party closed."); | ||
console.log("Party closed: " + close); | ||
} | ||
@@ -961,7 +995,7 @@ } | ||
PartyJoinRequestList | PartyLeave | PartyMatchmakerAdd | PartyMatchmakerRemove | PartyPromote | | ||
PartyRemove | Rpc | StatusFollow | StatusUnfollow | StatusUpdate): Promise<any> { | ||
PartyRemove | Rpc | StatusFollow | StatusUnfollow | StatusUpdate | Ping, sendTimeout = DefaultSocket.DefaultSendTimeoutMs): Promise<any> { | ||
const untypedMessage = message as any; | ||
return new Promise<void>((resolve, reject) => { | ||
if (!this.adapter.isConnected) { | ||
if (!this.adapter.isOpen()) { | ||
reject("Socket connection has not been established yet."); | ||
@@ -988,2 +1022,5 @@ } | ||
this.cIds[cid] = {resolve, reject}; | ||
setTimeout(() => { | ||
reject("The socket timed out while waiting for a response.") | ||
}, sendTimeout); | ||
@@ -1196,2 +1233,25 @@ /** Add id for promise executor. */ | ||
} | ||
private async pingPong() : Promise<void> { | ||
if (!this.adapter.isOpen()) { | ||
return; | ||
} | ||
try { | ||
await this.send({ping: {}}, this._heartbeatTimeoutMs); | ||
} catch { | ||
if (this.adapter.isOpen()) { | ||
if (window && window.console) { | ||
console.error("Server unreachable from heartbeat."); | ||
} | ||
this.adapter.close(); | ||
} | ||
return; | ||
} | ||
// reuse the timeout as the interval for now. | ||
// we can separate them out into separate values if needed later. | ||
setTimeout(() => this.pingPong(), this._heartbeatTimeoutMs); | ||
} | ||
}; |
@@ -45,3 +45,3 @@ /** | ||
readonly isConnected: boolean; | ||
isOpen(): boolean; | ||
close() : void; | ||
@@ -85,5 +85,2 @@ connect(scheme: string, host: string, port : string, createStatus: boolean, token : string) : void; | ||
export class WebSocketAdapterText implements WebSocketAdapter { | ||
private _isConnected: boolean = false; | ||
private _socket?: WebSocket; | ||
@@ -138,4 +135,4 @@ | ||
get isConnected(): boolean { | ||
return this._isConnected; | ||
isOpen(): boolean { | ||
return this._socket?.readyState == WebSocket.OPEN; | ||
} | ||
@@ -146,7 +143,5 @@ | ||
this._socket = new WebSocket(url); | ||
this._isConnected = true; | ||
} | ||
close() { | ||
this._isConnected = false; | ||
this._socket!.close(); | ||
@@ -153,0 +148,0 @@ this._socket = undefined; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1014604
188
17963
221