Webatrice websocket refactor (#4435)
* add unit tests for websocket events * add unit tests for KeepAliveService, clean up keepAlive termination flow * put keepAlive command in protobuf service and expose thru webClient * secure wss * rename files tsx to ts * add localhost support for ws/wss connection Co-authored-by: Jeremy Letto <jeremy.letto@datasite.com>
This commit is contained in:
parent
f75ff2a7c8
commit
586f23cfa9
15 changed files with 568 additions and 77 deletions
|
@ -69,14 +69,13 @@ export class WebClient {
|
||||||
SessionPersistence.updateStatus(status, description);
|
SessionPersistence.updateStatus(status, description);
|
||||||
|
|
||||||
if (status === StatusEnum.DISCONNECTED) {
|
if (status === StatusEnum.DISCONNECTED) {
|
||||||
this.resetConnectionvars();
|
this.protobuf.resetCommands();
|
||||||
this.clearStores();
|
this.clearStores();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public resetConnectionvars() {
|
public keepAlive(pingReceived: Function) {
|
||||||
this.protobuf.resetCommands();
|
this.protobuf.sendKeepAliveCommand(pingReceived);
|
||||||
this.socket.keepAliveService.resetPingFlag();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private clearStores() {
|
private clearStores() {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { RoomPersistence } from '../persistence';
|
||||||
import webClient from "../WebClient";
|
import webClient from "../WebClient";
|
||||||
|
|
||||||
export class RoomCommands {
|
export class RoomCommands {
|
||||||
static roomSay(roomId: number, message: string) {
|
static roomSay(roomId: number, message: string): void {
|
||||||
const trimmed = message.trim();
|
const trimmed = message.trim();
|
||||||
|
|
||||||
if (!trimmed) return;
|
if (!trimmed) return;
|
||||||
|
@ -18,7 +18,7 @@ export class RoomCommands {
|
||||||
webClient.protobuf.sendRoomCommand(roomId, rc);
|
webClient.protobuf.sendRoomCommand(roomId, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static leaveRoom(roomId: number) {
|
static leaveRoom(roomId: number): void {
|
||||||
var CmdLeaveRoom = webClient.protobuf.controller.Command_LeaveRoom.create();
|
var CmdLeaveRoom = webClient.protobuf.controller.Command_LeaveRoom.create();
|
||||||
|
|
||||||
var rc = webClient.protobuf.controller.RoomCommand.create({
|
var rc = webClient.protobuf.controller.RoomCommand.create({
|
||||||
|
|
|
@ -6,17 +6,17 @@ import webClient from '../WebClient';
|
||||||
import { guid } from '../utils';
|
import { guid } from '../utils';
|
||||||
|
|
||||||
export class SessionCommands {
|
export class SessionCommands {
|
||||||
static connect(options: ServerConnectParams) {
|
static connect(options: ServerConnectParams): void {
|
||||||
SessionCommands.updateStatus(StatusEnum.CONNECTING, 'Connecting...');
|
SessionCommands.updateStatus(StatusEnum.CONNECTING, 'Connecting...');
|
||||||
webClient.connect(options);
|
webClient.connect(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
static disconnect() {
|
static disconnect(): void {
|
||||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTING, 'Disconnecting...');
|
SessionCommands.updateStatus(StatusEnum.DISCONNECTING, 'Disconnecting...');
|
||||||
webClient.disconnect();
|
webClient.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
static login() {
|
static login(): void {
|
||||||
const loginConfig = {
|
const loginConfig = {
|
||||||
...webClient.clientConfig,
|
...webClient.clientConfig,
|
||||||
userName: webClient.options.user,
|
userName: webClient.options.user,
|
||||||
|
@ -86,7 +86,7 @@ export class SessionCommands {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static listUsers() {
|
static listUsers(): void {
|
||||||
const CmdListUsers = webClient.protobuf.controller.Command_ListUsers.create();
|
const CmdListUsers = webClient.protobuf.controller.Command_ListUsers.create();
|
||||||
|
|
||||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||||
|
@ -110,7 +110,7 @@ export class SessionCommands {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static listRooms() {
|
static listRooms(): void {
|
||||||
const CmdListRooms = webClient.protobuf.controller.Command_ListRooms.create();
|
const CmdListRooms = webClient.protobuf.controller.Command_ListRooms.create();
|
||||||
|
|
||||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||||
|
@ -120,7 +120,7 @@ export class SessionCommands {
|
||||||
webClient.protobuf.sendSessionCommand(sc);
|
webClient.protobuf.sendSessionCommand(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static joinRoom(roomId: number) {
|
static joinRoom(roomId: number): void {
|
||||||
const CmdJoinRoom = webClient.protobuf.controller.Command_JoinRoom.create({ roomId });
|
const CmdJoinRoom = webClient.protobuf.controller.Command_JoinRoom.create({ roomId });
|
||||||
|
|
||||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||||
|
@ -158,23 +158,23 @@ export class SessionCommands {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static addToBuddyList(userName: string) {
|
static addToBuddyList(userName: string): void {
|
||||||
this.addToList('buddy', userName);
|
this.addToList('buddy', userName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static removeFromBuddyList(userName: string) {
|
static removeFromBuddyList(userName: string): void {
|
||||||
this.removeFromList('buddy', userName);
|
this.removeFromList('buddy', userName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static addToIgnoreList(userName: string) {
|
static addToIgnoreList(userName: string): void {
|
||||||
this.addToList('ignore', userName);
|
this.addToList('ignore', userName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static removeFromIgnoreList(userName: string) {
|
static removeFromIgnoreList(userName: string): void {
|
||||||
this.removeFromList('ignore', userName);
|
this.removeFromList('ignore', userName);
|
||||||
}
|
}
|
||||||
|
|
||||||
static addToList(list: string, userName: string) {
|
static addToList(list: string, userName: string): void {
|
||||||
const CmdAddToList = webClient.protobuf.controller.Command_AddToList.create({ list, userName });
|
const CmdAddToList = webClient.protobuf.controller.Command_AddToList.create({ list, userName });
|
||||||
|
|
||||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||||
|
@ -186,7 +186,7 @@ export class SessionCommands {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static removeFromList(list: string, userName: string) {
|
static removeFromList(list: string, userName: string): void {
|
||||||
const CmdRemoveFromList = webClient.protobuf.controller.Command_RemoveFromList.create({ list, userName });
|
const CmdRemoveFromList = webClient.protobuf.controller.Command_RemoveFromList.create({ list, userName });
|
||||||
|
|
||||||
const sc = webClient.protobuf.controller.SessionCommand.create({
|
const sc = webClient.protobuf.controller.SessionCommand.create({
|
||||||
|
@ -198,7 +198,7 @@ export class SessionCommands {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static viewLogHistory(filters) {
|
static viewLogHistory(filters): void {
|
||||||
const CmdViewLogHistory = webClient.protobuf.controller.Command_ViewLogHistory.create(filters);
|
const CmdViewLogHistory = webClient.protobuf.controller.Command_ViewLogHistory.create(filters);
|
||||||
|
|
||||||
const sc = webClient.protobuf.controller.ModeratorCommand.create({
|
const sc = webClient.protobuf.controller.ModeratorCommand.create({
|
||||||
|
@ -226,7 +226,7 @@ export class SessionCommands {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static updateStatus(status: StatusEnum, description: string) {
|
static updateStatus(status: StatusEnum, description: string): void {
|
||||||
webClient.updateStatus(status, description);
|
webClient.updateStatus(status, description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
64
webclient/src/websocket/events/RoomEvents.spec.ts
Normal file
64
webclient/src/websocket/events/RoomEvents.spec.ts
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
import { Message } from 'types';
|
||||||
|
|
||||||
|
import {
|
||||||
|
RoomEvents,
|
||||||
|
RoomEvent,
|
||||||
|
JoinRoomData,
|
||||||
|
LeaveRoomData,
|
||||||
|
ListGamesData,
|
||||||
|
} from './RoomEvents';
|
||||||
|
import { RoomPersistence } from '../persistence/RoomPersistence';
|
||||||
|
|
||||||
|
describe('RoomEvents', () => {
|
||||||
|
it('.Event_JoinRoom.ext should call RoomPersistence.userJoined', () => {
|
||||||
|
spyOn(RoomPersistence, 'userJoined');
|
||||||
|
const data: JoinRoomData = { userInfo: {} as any };
|
||||||
|
const event: RoomEvent = { roomEvent: { roomId: 1 } };
|
||||||
|
|
||||||
|
RoomEvents['.Event_JoinRoom.ext'](data, event);
|
||||||
|
|
||||||
|
expect(RoomPersistence.userJoined).toHaveBeenCalledWith(
|
||||||
|
event.roomEvent.roomId,
|
||||||
|
data.userInfo
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('.Event_LeaveRoom.ext should call RoomPersistence.userLeft', () => {
|
||||||
|
spyOn(RoomPersistence, 'userLeft');
|
||||||
|
const data: LeaveRoomData = { name: '' };
|
||||||
|
const event: RoomEvent = { roomEvent: { roomId: 1 } };
|
||||||
|
|
||||||
|
RoomEvents['.Event_LeaveRoom.ext'](data, event);
|
||||||
|
|
||||||
|
expect(RoomPersistence.userLeft).toHaveBeenCalledWith(
|
||||||
|
event.roomEvent.roomId,
|
||||||
|
data.name
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('.Event_ListGames.ext should call RoomPersistence.updateGames', () => {
|
||||||
|
spyOn(RoomPersistence, 'updateGames');
|
||||||
|
const data: ListGamesData = { gameList: [] };
|
||||||
|
const event: RoomEvent = { roomEvent: { roomId: 1 } };
|
||||||
|
|
||||||
|
RoomEvents['.Event_ListGames.ext'](data, event);
|
||||||
|
|
||||||
|
expect(RoomPersistence.updateGames).toHaveBeenCalledWith(
|
||||||
|
event.roomEvent.roomId,
|
||||||
|
data.gameList
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('.Event_RoomSay.ext should call RoomPersistence.addMessage', () => {
|
||||||
|
spyOn(RoomPersistence, 'addMessage');
|
||||||
|
const data: Message = {} as any;
|
||||||
|
const event: RoomEvent = { roomEvent: { roomId: 1 } };
|
||||||
|
|
||||||
|
RoomEvents['.Event_RoomSay.ext'](data, event);
|
||||||
|
|
||||||
|
expect(RoomPersistence.addMessage).toHaveBeenCalledWith(
|
||||||
|
event.roomEvent.roomId,
|
||||||
|
data
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
|
@ -30,20 +30,20 @@ function roomSay(message: Message, { roomEvent }: RoomEvent) {
|
||||||
RoomPersistence.addMessage(roomId, message);
|
RoomPersistence.addMessage(roomId, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RoomEvent {
|
export interface RoomEvent {
|
||||||
roomEvent: {
|
roomEvent: {
|
||||||
roomId: number;
|
roomId: number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface JoinRoomData {
|
export interface JoinRoomData {
|
||||||
userInfo: User;
|
userInfo: User;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LeaveRoomData {
|
export interface LeaveRoomData {
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ListGamesData {
|
export interface ListGamesData {
|
||||||
gameList: Game[];
|
gameList: Game[];
|
||||||
}
|
}
|
||||||
|
|
355
webclient/src/websocket/events/SessionEvents.spec.ts
Normal file
355
webclient/src/websocket/events/SessionEvents.spec.ts
Normal file
|
@ -0,0 +1,355 @@
|
||||||
|
import { StatusEnum } from "types";
|
||||||
|
|
||||||
|
import {
|
||||||
|
SessionEvents,
|
||||||
|
SessionEvent,
|
||||||
|
AddToListData,
|
||||||
|
ConnectionClosedData,
|
||||||
|
ListRoomsData,
|
||||||
|
RemoveFromListData,
|
||||||
|
ServerIdentificationData,
|
||||||
|
ServerMessageData,
|
||||||
|
UserJoinedData,
|
||||||
|
UserLeftData,
|
||||||
|
} from './SessionEvents';
|
||||||
|
|
||||||
|
import { SessionCommands } from "../commands";
|
||||||
|
import { RoomPersistence, SessionPersistence } from '../persistence';
|
||||||
|
import webClient from '../WebClient';
|
||||||
|
|
||||||
|
describe('SessionEvents', () => {
|
||||||
|
const roomId = 1;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(SessionCommands, 'updateStatus');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.Event_AddToList.ext', () => {
|
||||||
|
it('should call SessionPersistence.addToBuddyList if buddy listName', () => {
|
||||||
|
spyOn(SessionPersistence, 'addToBuddyList');
|
||||||
|
const data: AddToListData = { listName: 'buddy', userInfo: {} as any };
|
||||||
|
|
||||||
|
SessionEvents['.Event_AddToList.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionPersistence.addToBuddyList).toHaveBeenCalledWith(
|
||||||
|
data.userInfo
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call SessionPersistence.addToIgnoreList if ignore listName', () => {
|
||||||
|
spyOn(SessionPersistence, 'addToIgnoreList');
|
||||||
|
const data: AddToListData = { listName: 'ignore', userInfo: {} as any };
|
||||||
|
|
||||||
|
SessionEvents['.Event_AddToList.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionPersistence.addToIgnoreList).toHaveBeenCalledWith(
|
||||||
|
data.userInfo
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call console.log if unknown listName', () => {
|
||||||
|
spyOn(console, 'log');
|
||||||
|
const data: AddToListData = { listName: 'unknown', userInfo: {} as any };
|
||||||
|
|
||||||
|
SessionEvents['.Event_AddToList.ext'](data);
|
||||||
|
|
||||||
|
expect(console.log).toHaveBeenCalledWith(
|
||||||
|
`Attempted to add to unknown list: ${data.listName}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.Event_ConnectionClosed.ext', () => {
|
||||||
|
describe('with reasonStr', () => {
|
||||||
|
it('should call SessionCommands.updateStatus', () => {
|
||||||
|
const data: ConnectionClosedData = { endTime: 0, reason: 0, reasonStr: 'reasonStr' };
|
||||||
|
|
||||||
|
SessionEvents['.Event_ConnectionClosed.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionCommands.updateStatus).toHaveBeenCalledWith(
|
||||||
|
StatusEnum.DISCONNECTED,
|
||||||
|
data.reasonStr
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('without reasonStr', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
webClient.protobuf.controller.Event_ConnectionClosed = { CloseReason: {} };
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('USER_LIMIT_REACHED', () => {
|
||||||
|
it('should call SessionCommands.updateStatus', () => {
|
||||||
|
const USER_LIMIT_REACHED = 1;
|
||||||
|
webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.USER_LIMIT_REACHED = USER_LIMIT_REACHED;
|
||||||
|
const data: ConnectionClosedData = { endTime: 0, reason: USER_LIMIT_REACHED, reasonStr: null };
|
||||||
|
|
||||||
|
SessionEvents['.Event_ConnectionClosed.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionCommands.updateStatus).toHaveBeenCalledWith(
|
||||||
|
StatusEnum.DISCONNECTED,
|
||||||
|
'The server has reached its maximum user capacity'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('TOO_MANY_CONNECTIONS', () => {
|
||||||
|
it('should call SessionCommands.updateStatus', () => {
|
||||||
|
const TOO_MANY_CONNECTIONS = 1;
|
||||||
|
webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.TOO_MANY_CONNECTIONS = TOO_MANY_CONNECTIONS;
|
||||||
|
const data: ConnectionClosedData = { endTime: 0, reason: TOO_MANY_CONNECTIONS, reasonStr: null };
|
||||||
|
|
||||||
|
SessionEvents['.Event_ConnectionClosed.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionCommands.updateStatus).toHaveBeenCalledWith(
|
||||||
|
StatusEnum.DISCONNECTED,
|
||||||
|
'There are too many concurrent connections from your address'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('BANNED', () => {
|
||||||
|
it('should call SessionCommands.updateStatus', () => {
|
||||||
|
const BANNED = 1;
|
||||||
|
webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.BANNED = BANNED;
|
||||||
|
const data: ConnectionClosedData = { endTime: 0, reason: BANNED, reasonStr: null };
|
||||||
|
|
||||||
|
SessionEvents['.Event_ConnectionClosed.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionCommands.updateStatus).toHaveBeenCalledWith(
|
||||||
|
StatusEnum.DISCONNECTED,
|
||||||
|
'You are banned'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('DEMOTED', () => {
|
||||||
|
it('should call SessionCommands.updateStatus', () => {
|
||||||
|
const DEMOTED = 1;
|
||||||
|
webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.DEMOTED = DEMOTED;
|
||||||
|
const data: ConnectionClosedData = { endTime: 0, reason: DEMOTED, reasonStr: null };
|
||||||
|
|
||||||
|
SessionEvents['.Event_ConnectionClosed.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionCommands.updateStatus).toHaveBeenCalledWith(
|
||||||
|
StatusEnum.DISCONNECTED,
|
||||||
|
'You were demoted'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('SERVER_SHUTDOWN', () => {
|
||||||
|
it('should call SessionCommands.updateStatus', () => {
|
||||||
|
const SERVER_SHUTDOWN = 1;
|
||||||
|
webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.SERVER_SHUTDOWN = SERVER_SHUTDOWN;
|
||||||
|
const data: ConnectionClosedData = { endTime: 0, reason: SERVER_SHUTDOWN, reasonStr: null };
|
||||||
|
|
||||||
|
SessionEvents['.Event_ConnectionClosed.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionCommands.updateStatus).toHaveBeenCalledWith(
|
||||||
|
StatusEnum.DISCONNECTED,
|
||||||
|
'Scheduled server shutdown'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('USERNAMEINVALID', () => {
|
||||||
|
it('should call SessionCommands.updateStatus', () => {
|
||||||
|
const USERNAMEINVALID = 1;
|
||||||
|
webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.USERNAMEINVALID = USERNAMEINVALID;
|
||||||
|
const data: ConnectionClosedData = { endTime: 0, reason: USERNAMEINVALID, reasonStr: null };
|
||||||
|
|
||||||
|
SessionEvents['.Event_ConnectionClosed.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionCommands.updateStatus).toHaveBeenCalledWith(
|
||||||
|
StatusEnum.DISCONNECTED,
|
||||||
|
'Invalid username'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('LOGGEDINELSEWERE', () => {
|
||||||
|
it('should call SessionCommands.updateStatus', () => {
|
||||||
|
const LOGGEDINELSEWERE = 1;
|
||||||
|
webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.LOGGEDINELSEWERE = LOGGEDINELSEWERE;
|
||||||
|
const data: ConnectionClosedData = { endTime: 0, reason: LOGGEDINELSEWERE, reasonStr: null };
|
||||||
|
|
||||||
|
SessionEvents['.Event_ConnectionClosed.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionCommands.updateStatus).toHaveBeenCalledWith(
|
||||||
|
StatusEnum.DISCONNECTED,
|
||||||
|
'You have been logged out due to logging in at another location'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('OTHER', () => {
|
||||||
|
it('should call SessionCommands.updateStatus', () => {
|
||||||
|
const OTHER = 1;
|
||||||
|
webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.OTHER = OTHER;
|
||||||
|
const data: ConnectionClosedData = { endTime: 0, reason: OTHER, reasonStr: null };
|
||||||
|
|
||||||
|
SessionEvents['.Event_ConnectionClosed.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionCommands.updateStatus).toHaveBeenCalledWith(
|
||||||
|
StatusEnum.DISCONNECTED,
|
||||||
|
'Unknown reason'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('UNKNOWN', () => {
|
||||||
|
it('should call SessionCommands.updateStatus', () => {
|
||||||
|
const UNKNOWN = 1;
|
||||||
|
webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.UNKNOWN = UNKNOWN;
|
||||||
|
const data: ConnectionClosedData = { endTime: 0, reason: UNKNOWN, reasonStr: null };
|
||||||
|
|
||||||
|
SessionEvents['.Event_ConnectionClosed.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionCommands.updateStatus).toHaveBeenCalledWith(
|
||||||
|
StatusEnum.DISCONNECTED,
|
||||||
|
'Unknown reason'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.Event_ListRooms.ext', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
webClient.options.autojoinrooms = false;
|
||||||
|
spyOn(RoomPersistence, 'updateRooms');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call RoomPersistence.updateRooms', () => {
|
||||||
|
const data: ListRoomsData = { roomList: [{ roomId, autoJoin: false } as any] };
|
||||||
|
|
||||||
|
SessionEvents['.Event_ListRooms.ext'](data);
|
||||||
|
|
||||||
|
expect(RoomPersistence.updateRooms).toHaveBeenCalledWith(data.roomList);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call SessionCommands.joinRoom if webClient and room is configured for autojoin', () => {
|
||||||
|
webClient.options.autojoinrooms = true;
|
||||||
|
spyOn(SessionCommands, 'joinRoom');
|
||||||
|
const data: ListRoomsData = { roomList: [{ roomId, autoJoin: true } as any, { roomId: 2, autoJoin: false } as any] };
|
||||||
|
|
||||||
|
SessionEvents['.Event_ListRooms.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionCommands.joinRoom).toHaveBeenCalledTimes(1);
|
||||||
|
expect(SessionCommands.joinRoom).toHaveBeenCalledWith(data.roomList[0].roomId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.Event_RemoveFromList.ext', () => {
|
||||||
|
it('should call SessionPersistence.removeFromBuddyList if buddy listName', () => {
|
||||||
|
spyOn(SessionPersistence, 'removeFromBuddyList');
|
||||||
|
const data: RemoveFromListData = { listName: 'buddy', userName: '' };
|
||||||
|
|
||||||
|
SessionEvents['.Event_RemoveFromList.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionPersistence.removeFromBuddyList).toHaveBeenCalledWith(
|
||||||
|
data.userName
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call SessionPersistence.removeFromIgnoreList if ignore listName', () => {
|
||||||
|
spyOn(SessionPersistence, 'removeFromIgnoreList');
|
||||||
|
const data: RemoveFromListData = { listName: 'ignore', userName: '' };
|
||||||
|
|
||||||
|
SessionEvents['.Event_RemoveFromList.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionPersistence.removeFromIgnoreList).toHaveBeenCalledWith(
|
||||||
|
data.userName
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call console.log if unknown listName', () => {
|
||||||
|
spyOn(console, 'log');
|
||||||
|
const data: RemoveFromListData = { listName: 'unknown', userName: '' };
|
||||||
|
|
||||||
|
SessionEvents['.Event_RemoveFromList.ext'](data);
|
||||||
|
|
||||||
|
expect(console.log).toHaveBeenCalledWith(
|
||||||
|
`Attempted to remove from unknown list: ${data.listName}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.Event_ServerIdentification.ext', () => {
|
||||||
|
it('update status/info and login', () => {
|
||||||
|
spyOn(SessionPersistence, 'updateInfo');
|
||||||
|
spyOn(SessionCommands, 'login');
|
||||||
|
|
||||||
|
webClient.protocolVersion = 0;
|
||||||
|
const data: ServerIdentificationData = {
|
||||||
|
serverName: 'serverName',
|
||||||
|
serverVersion: 'serverVersion',
|
||||||
|
protocolVersion: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
SessionEvents['.Event_ServerIdentification.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionPersistence.updateInfo).toHaveBeenCalledWith(data.serverName, data.serverVersion);
|
||||||
|
expect(SessionCommands.updateStatus).toHaveBeenCalledWith(StatusEnum.LOGGINGIN, 'Logging in...');
|
||||||
|
expect(SessionCommands.login).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should disconnect if protocolVersion mismatched', () => {
|
||||||
|
spyOn(SessionCommands, 'login');
|
||||||
|
spyOn(SessionCommands, 'disconnect');
|
||||||
|
|
||||||
|
webClient.protocolVersion = 0;
|
||||||
|
const data: ServerIdentificationData = {
|
||||||
|
serverName: '',
|
||||||
|
serverVersion: '',
|
||||||
|
protocolVersion: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
SessionEvents['.Event_ServerIdentification.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionCommands.disconnect).toHaveBeenCalled();
|
||||||
|
expect(SessionCommands.updateStatus).toHaveBeenCalledWith(StatusEnum.DISCONNECTED, `Protocol version mismatch: ${data.protocolVersion}`);
|
||||||
|
expect(SessionCommands.login).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.Event_ServerMessage.ext', () => {
|
||||||
|
it('should call SessionPersistence.serverMessage', () => {
|
||||||
|
spyOn(SessionPersistence, 'serverMessage');
|
||||||
|
const data: ServerMessageData = { message: 'message' };
|
||||||
|
|
||||||
|
SessionEvents['.Event_ServerMessage.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionPersistence.serverMessage).toHaveBeenCalledWith(
|
||||||
|
data.message
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.Event_UserJoined.ext', () => {
|
||||||
|
it('should call SessionPersistence.userJoined', () => {
|
||||||
|
spyOn(SessionPersistence, 'userJoined');
|
||||||
|
const data: UserJoinedData = { userInfo: {} as any };
|
||||||
|
|
||||||
|
SessionEvents['.Event_UserJoined.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionPersistence.userJoined).toHaveBeenCalledWith(
|
||||||
|
data.userInfo
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.Event_UserLeft.ext', () => {
|
||||||
|
it('should call SessionPersistence.userLeft', () => {
|
||||||
|
spyOn(SessionPersistence, 'userLeft');
|
||||||
|
const data: UserLeftData = { name: '' };
|
||||||
|
|
||||||
|
SessionEvents['.Event_UserLeft.ext'](data);
|
||||||
|
|
||||||
|
expect(SessionPersistence.userLeft).toHaveBeenCalledWith(
|
||||||
|
data.name
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,23 +1,23 @@
|
||||||
import { Room, StatusEnum, User } from "types";
|
import { Room, StatusEnum, User } from 'types';
|
||||||
|
|
||||||
import { SessionCommands } from "../commands";
|
import { SessionCommands } from '../commands';
|
||||||
import { RoomPersistence, SessionPersistence } from '../persistence';
|
import { RoomPersistence, SessionPersistence } from '../persistence';
|
||||||
import { ProtobufEvents } from '../services/ProtobufService';
|
import { ProtobufEvents } from '../services/ProtobufService';
|
||||||
import webClient from '../WebClient';
|
import webClient from '../WebClient';
|
||||||
|
|
||||||
export const SessionEvents: ProtobufEvents = {
|
export const SessionEvents: ProtobufEvents = {
|
||||||
".Event_AddToList.ext": addToList,
|
'.Event_AddToList.ext': addToList,
|
||||||
".Event_ConnectionClosed.ext": connectionClosed,
|
'.Event_ConnectionClosed.ext': connectionClosed,
|
||||||
".Event_ListRooms.ext": listRooms,
|
'.Event_ListRooms.ext': listRooms,
|
||||||
".Event_NotifyUser.ext": notifyUser,
|
'.Event_NotifyUser.ext': notifyUser,
|
||||||
".Event_PlayerPropertiesChanges.ext": playerPropertiesChanges,
|
'.Event_PlayerPropertiesChanges.ext': playerPropertiesChanges,
|
||||||
".Event_RemoveFromList.ext": removeFromList,
|
'.Event_RemoveFromList.ext': removeFromList,
|
||||||
".Event_ServerIdentification.ext": serverIdentification,
|
'.Event_ServerIdentification.ext': serverIdentification,
|
||||||
".Event_ServerMessage.ext": serverMessage,
|
'.Event_ServerMessage.ext': serverMessage,
|
||||||
".Event_ServerShutdown.ext": serverShutdown,
|
'.Event_ServerShutdown.ext': serverShutdown,
|
||||||
".Event_UserJoined.ext": userJoined,
|
'.Event_UserJoined.ext': userJoined,
|
||||||
".Event_UserLeft.ext": userLeft,
|
'.Event_UserLeft.ext': userLeft,
|
||||||
".Event_UserMessage.ext": userMessage,
|
'.Event_UserMessage.ext': userMessage,
|
||||||
}
|
}
|
||||||
|
|
||||||
function addToList({ listName, userInfo}: AddToListData) {
|
function addToList({ listName, userInfo}: AddToListData) {
|
||||||
|
@ -31,13 +31,13 @@ function addToList({ listName, userInfo}: AddToListData) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
console.log('Attempted to add to unknown list: ', listName);
|
console.log(`Attempted to add to unknown list: ${listName}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function connectionClosed({ reason, reasonStr }: ConnectionClosedData) {
|
function connectionClosed({ reason, reasonStr }: ConnectionClosedData) {
|
||||||
let message = "";
|
let message = '';
|
||||||
|
|
||||||
// @TODO (5)
|
// @TODO (5)
|
||||||
if (reasonStr) {
|
if (reasonStr) {
|
||||||
|
@ -45,29 +45,29 @@ function connectionClosed({ reason, reasonStr }: ConnectionClosedData) {
|
||||||
} else {
|
} else {
|
||||||
switch(reason) {
|
switch(reason) {
|
||||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.USER_LIMIT_REACHED:
|
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.USER_LIMIT_REACHED:
|
||||||
message = "The server has reached its maximum user capacity";
|
message = 'The server has reached its maximum user capacity';
|
||||||
break;
|
break;
|
||||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.TOO_MANY_CONNECTIONS:
|
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.TOO_MANY_CONNECTIONS:
|
||||||
message = "There are too many concurrent connections from your address";
|
message = 'There are too many concurrent connections from your address';
|
||||||
break;
|
break;
|
||||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.BANNED:
|
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.BANNED:
|
||||||
message = "You are banned";
|
message = 'You are banned';
|
||||||
break;
|
break;
|
||||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.DEMOTED:
|
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.DEMOTED:
|
||||||
message = "You were demoted";
|
message = 'You were demoted';
|
||||||
break;
|
break;
|
||||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.SERVER_SHUTDOWN:
|
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.SERVER_SHUTDOWN:
|
||||||
message = "Scheduled server shutdown";
|
message = 'Scheduled server shutdown';
|
||||||
break;
|
break;
|
||||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.USERNAMEINVALID:
|
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.USERNAMEINVALID:
|
||||||
message = "Invalid username";
|
message = 'Invalid username';
|
||||||
break;
|
break;
|
||||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.LOGGEDINELSEWERE:
|
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.LOGGEDINELSEWERE:
|
||||||
message = "You have been logged out due to logging in at another location";
|
message = 'You have been logged out due to logging in at another location';
|
||||||
break;
|
break;
|
||||||
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.OTHER:
|
case webClient.protobuf.controller.Event_ConnectionClosed.CloseReason.OTHER:
|
||||||
default:
|
default:
|
||||||
message = "Unknown reason";
|
message = 'Unknown reason';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,11 +88,11 @@ function listRooms({ roomList }: ListRoomsData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function notifyUser(payload) {
|
function notifyUser(payload) {
|
||||||
// console.info("Event_NotifyUser", payload);
|
// console.info('Event_NotifyUser', payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
function playerPropertiesChanges(payload) {
|
function playerPropertiesChanges(payload) {
|
||||||
// console.info("Event_PlayerPropertiesChanges", payload);
|
// console.info('Event_PlayerPropertiesChanges', payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeFromList({ listName, userName }: RemoveFromListData) {
|
function removeFromList({ listName, userName }: RemoveFromListData) {
|
||||||
|
@ -106,7 +106,7 @@ function removeFromList({ listName, userName }: RemoveFromListData) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
console.log('Attempted to remove from unknown list: ', listName);
|
console.log(`Attempted to remove from unknown list: ${listName}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,13 +116,12 @@ function serverIdentification(info: ServerIdentificationData) {
|
||||||
|
|
||||||
if (protocolVersion !== webClient.protocolVersion) {
|
if (protocolVersion !== webClient.protocolVersion) {
|
||||||
SessionCommands.disconnect();
|
SessionCommands.disconnect();
|
||||||
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, "Protocol version mismatch: " + protocolVersion);
|
SessionCommands.updateStatus(StatusEnum.DISCONNECTED, `Protocol version mismatch: ${protocolVersion}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
webClient.resetConnectionvars();
|
|
||||||
SessionPersistence.updateInfo(serverName, serverVersion);
|
SessionPersistence.updateInfo(serverName, serverVersion);
|
||||||
SessionCommands.updateStatus(StatusEnum.LOGGINGIN, "Logging in...");
|
SessionCommands.updateStatus(StatusEnum.LOGGINGIN, 'Logging in...');
|
||||||
SessionCommands.login();
|
SessionCommands.login();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +130,7 @@ function serverMessage({ message }: ServerMessageData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function serverShutdown(payload) {
|
function serverShutdown(payload) {
|
||||||
// console.info("Event_ServerShutdown", payload);
|
// console.info('Event_ServerShutdown', payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
function userJoined({ userInfo }: UserJoinedData) {
|
function userJoined({ userInfo }: UserJoinedData) {
|
||||||
|
@ -143,47 +142,47 @@ function userLeft({ name }: UserLeftData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function userMessage(payload) {
|
function userMessage(payload) {
|
||||||
// console.info("Event_UserMessage", payload);
|
// console.info('Event_UserMessage', payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SessionEvent {
|
export interface SessionEvent {
|
||||||
sessionEvent: {}
|
sessionEvent: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AddToListData {
|
export interface AddToListData {
|
||||||
listName: string;
|
listName: string;
|
||||||
userInfo: User;
|
userInfo: User;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ConnectionClosedData {
|
export interface ConnectionClosedData {
|
||||||
endTime: number;
|
endTime: number;
|
||||||
reason: number;
|
reason: number;
|
||||||
reasonStr: string;
|
reasonStr: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ListRoomsData {
|
export interface ListRoomsData {
|
||||||
roomList: Room[];
|
roomList: Room[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RemoveFromListData {
|
export interface RemoveFromListData {
|
||||||
listName: string;
|
listName: string;
|
||||||
userName: string;
|
userName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ServerIdentificationData {
|
export interface ServerIdentificationData {
|
||||||
protocolVersion: number;
|
protocolVersion: number;
|
||||||
serverName: string;
|
serverName: string;
|
||||||
serverVersion: string;
|
serverVersion: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ServerMessageData {
|
export interface ServerMessageData {
|
||||||
message: string;
|
message: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UserJoinedData {
|
export interface UserJoinedData {
|
||||||
userInfo: User;
|
userInfo: User;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UserLeftData {
|
export interface UserLeftData {
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
71
webclient/src/websocket/services/KeepAliveService.spec.ts
Normal file
71
webclient/src/websocket/services/KeepAliveService.spec.ts
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
import { KeepAliveService } from './KeepAliveService';
|
||||||
|
import { WebSocketService } from "./WebSocketService";
|
||||||
|
|
||||||
|
import webClient from '../WebClient';
|
||||||
|
|
||||||
|
describe('KeepAliveService', () => {
|
||||||
|
let service: KeepAliveService;
|
||||||
|
let socket: WebSocketService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
|
||||||
|
socket = new WebSocketService(webClient);
|
||||||
|
service = new KeepAliveService(socket);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(service).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('startPingLoop', () => {
|
||||||
|
let resolvePing;
|
||||||
|
let interval;
|
||||||
|
let promise;
|
||||||
|
let ping;
|
||||||
|
let checkReadyStateSpy;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
interval = 100;
|
||||||
|
promise = new Promise(resolve => resolvePing = resolve);
|
||||||
|
ping = (done) => promise.then(done);
|
||||||
|
|
||||||
|
checkReadyStateSpy = spyOn(socket, 'checkReadyState');
|
||||||
|
checkReadyStateSpy.and.returnValue(true);
|
||||||
|
|
||||||
|
service.startPingLoop(interval, ping);
|
||||||
|
jest.advanceTimersByTime(interval);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should start ping loop', () => {
|
||||||
|
expect((service as any).keepalivecb).toBeDefined();
|
||||||
|
expect((service as any).lastPingPending).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call ping callback when done', (done: jest.DoneCallback) => {
|
||||||
|
resolvePing();
|
||||||
|
|
||||||
|
promise.then(() => {
|
||||||
|
expect((service as any).lastPingPending).toBeFalsy();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fire disconnected$ if lastPingPending is still true', () => {
|
||||||
|
spyOn(service.disconnected$, 'next');
|
||||||
|
jest.advanceTimersByTime(interval);
|
||||||
|
|
||||||
|
expect(service.disconnected$.next).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should endPingLoop if socket is not open', () => {
|
||||||
|
spyOn(service, 'endPingLoop');
|
||||||
|
checkReadyStateSpy.and.returnValue(false);
|
||||||
|
|
||||||
|
resolvePing();
|
||||||
|
jest.advanceTimersByTime(interval);
|
||||||
|
|
||||||
|
expect(service.endPingLoop).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -35,9 +35,6 @@ export class KeepAliveService {
|
||||||
public endPingLoop() {
|
public endPingLoop() {
|
||||||
clearInterval(this.keepalivecb);
|
clearInterval(this.keepalivecb);
|
||||||
this.keepalivecb = null;
|
this.keepalivecb = null;
|
||||||
}
|
|
||||||
|
|
||||||
public resetPingFlag() {
|
|
||||||
this.lastPingPending = false;
|
this.lastPingPending = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,14 @@ export class ProtobufService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sendKeepAliveCommand(pingReceived: Function) {
|
||||||
|
const command = this.controller.SessionCommand.create({
|
||||||
|
".Command_Ping.ext" : this.controller.Command_Ping.create()
|
||||||
|
});
|
||||||
|
|
||||||
|
this.sendSessionCommand(command, pingReceived);
|
||||||
|
}
|
||||||
|
|
||||||
public handleMessageEvent({ data }: MessageEvent): void {
|
public handleMessageEvent({ data }: MessageEvent): void {
|
||||||
try {
|
try {
|
||||||
const uint8msg = new Uint8Array(data);
|
const uint8msg = new Uint8Array(data);
|
||||||
|
|
|
@ -17,7 +17,7 @@ export interface WebSocketOptions {
|
||||||
export class WebSocketService {
|
export class WebSocketService {
|
||||||
private socket: WebSocket;
|
private socket: WebSocket;
|
||||||
private webClient: WebClient;
|
private webClient: WebClient;
|
||||||
public keepAliveService: KeepAliveService;
|
private keepAliveService: KeepAliveService;
|
||||||
|
|
||||||
public message$: Subject<MessageEvent> = new Subject();
|
public message$: Subject<MessageEvent> = new Subject();
|
||||||
public statusChange$: Subject<ServerStatus> = new Subject();
|
public statusChange$: Subject<ServerStatus> = new Subject();
|
||||||
|
@ -36,6 +36,10 @@ export class WebSocketService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public connect(options: WebSocketOptions, protocol: string = 'wss'): void {
|
public connect(options: WebSocketOptions, protocol: string = 'wss'): void {
|
||||||
|
if (window.location.hostname === 'localhost') {
|
||||||
|
protocol = 'ws';
|
||||||
|
}
|
||||||
|
|
||||||
const { host, port, keepalive } = options;
|
const { host, port, keepalive } = options;
|
||||||
this.keepalive = keepalive;
|
this.keepalive = keepalive;
|
||||||
|
|
||||||
|
@ -49,7 +53,7 @@ export class WebSocketService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public checkReadyState(state: number): boolean {
|
public checkReadyState(state: number): boolean {
|
||||||
return this.socket.readyState === state;
|
return this.socket?.readyState === state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public send(message): void {
|
public send(message): void {
|
||||||
|
@ -69,13 +73,7 @@ export class WebSocketService {
|
||||||
this.updateStatus(StatusEnum.CONNECTED, "Connected");
|
this.updateStatus(StatusEnum.CONNECTED, "Connected");
|
||||||
|
|
||||||
this.keepAliveService.startPingLoop(this.keepalive, (pingReceived: Function) => {
|
this.keepAliveService.startPingLoop(this.keepalive, (pingReceived: Function) => {
|
||||||
const command = this.webClient.protobuf.controller.SessionCommand.create({
|
this.webClient.keepAlive(pingReceived);
|
||||||
".Command_Ping.ext" : this.webClient.protobuf.controller.Command_Ping.create()
|
|
||||||
});
|
|
||||||
|
|
||||||
this.webClient.protobuf.sendSessionCommand(command, () => {
|
|
||||||
pingReceived();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue