[refactor]: move rtmt to core package

This commit is contained in:
Halit Aksoy 2024-06-17 17:25:40 +03:00
parent 597bb708f1
commit f371414f98
21 changed files with 74 additions and 137 deletions

View File

@ -1,14 +0,0 @@
import { Bytes } from "./rtmt"
var util= require('util');
const textEncoder = new util.TextEncoder()
const textDecoder = new util.TextDecoder("utf-8")
export function encodeText(text : string) {
const bytes = textEncoder.encode(text)
return bytes
}
export function decodeText(bytes : Bytes) {
return textDecoder.decode(bytes)
}

View File

@ -1,16 +1,8 @@
import { decodeText, encodeText } from "./byte_util";
import { Bytes } from "./rtmt";
const headerLenght = 4
export type Message = {
channel: string,
message: Object,
}
//
// channel is string, message is byte array
//
export function encode(message: Message) {
return JSON.stringify({
channel : message.channel,
@ -18,9 +10,6 @@ export function encode(message: Message) {
});
}
//
// return { channel : string, message : byte array}
//
export function decode(bytes: string): Message {
return JSON.parse(bytes);
}

View File

@ -1,4 +1,3 @@
export type Bytes = Buffer
export type OnMessage = (clientID: string, message: Object) => any
export type OnClientConnectionChange = (clientID: string, isOnline : boolean) => any

View File

@ -1,10 +1,10 @@
import { decode, encode } from "./encode_decode_message"
import { Bytes, OnClientConnectionChange, OnMessage, RTMT } from "./rtmt"
import { OnClientConnectionChange, OnMessage, RTMT } from "./rtmt"
import WebSocket from "ws"
import * as http from 'http';
import { channel_ping, channel_pong } from "@mancala/core";
import { RTMT_WS_PING_INTERVAL } from "../consts/config";
import { decode, encode } from "./encode_decode_message";
export class RTMTWS implements RTMT {

View File

@ -15,7 +15,8 @@
"author": "Halit Aksoy",
"license": "MIT",
"dependencies": {
"mancala.js": "^0.0.2-beta.3"
"mancala.js": "^0.0.2-beta.3",
"tiny-emitter": "^2.1.0"
},
"devDependencies": {
"@types/jest": "^27.4.1",

View File

@ -1,2 +1,2 @@
export * from './rtmt/channel_names'
export * from './models/index'
export * from './rtmt/index'

View File

@ -1,18 +1,19 @@
import EventEmitter2, { Listener } from "eventemitter2"
import { TinyEmitter } from "tiny-emitter"
export type Bytes = Uint8Array
export type OnMessage = (message : Object) => any
export type OnMessage = (message: Object) => any
export type ConnectionState = "none" | "connecting" | "error" | "connected" | "closed" | "reconnecting";
export type RtmtEventTypes = "open" | "close" | "connected" | "error" | "disconnected" | "message" | "connectionchange";
export interface RTMT extends EventEmitter2 {
get connectionState() : ConnectionState;
export const RTMT_WS_PING_INTERVAL = 1000, RTMT_WS_PING_INTERVAL_BUFFER_TIME = 2000;
export interface RTMT extends TinyEmitter {
get connectionState(): ConnectionState;
sendMessage: (channel: string, message: Object) => void;
addMessageListener(channel: string, callback: (message: any) => void);
removeMessageListener(channel: string, callback: (message: any) => void);
on(event: RtmtEventTypes, callback: (...value: any[]) => void): Listener | this;
addMessageListener(channel: string, callback: (message: any) => void): any;
removeMessageListener(channel: string, callback: (message: any) => void): any;
on(event: RtmtEventTypes, callback: (...value: any[]) => void): this;
off(event: RtmtEventTypes, callback: (...value: any[]) => void): this;
dispose();
dispose(): any;
}

View File

@ -1,16 +1,16 @@
import { decode, encode } from "./encode_decode_message";
import { channel_ping, channel_pong } from "@mancala/core";
import { RTMT_WS_PING_INTERVAL, RTMT_WS_PING_INTERVAL_BUFFER_TIME, server } from "../const/config";
import EventEmitter2, { Listener } from "eventemitter2";
import { Bytes, ConnectionState, RTMT, RtmtEventTypes } from "./rtmt";
import { channel_ping, channel_pong } from "../channel_names";
import { decode, encode } from "../encode_decode_message";
import { ConnectionState, RTMT, RTMT_WS_PING_INTERVAL, RTMT_WS_PING_INTERVAL_BUFFER_TIME, RtmtEventTypes } from "./rtmt";
import { TinyEmitter } from "tiny-emitter";
const MESSAGE_CHANNEL_PREFIX = "message_channel";
export class RTMTWS extends EventEmitter2 implements RTMT {
export class RTMTWS extends TinyEmitter implements RTMT {
private webSocket?: WebSocket;
private pingTimeout?: number = undefined;
private _connectionState: ConnectionState = "none";
private userKey: string;
private userKey: string = "";
private url: string = "";
get connectionState(): ConnectionState {
return this._connectionState;
@ -21,12 +21,11 @@ export class RTMTWS extends EventEmitter2 implements RTMT {
this.emit("connectionchange", this._connectionState);
}
private createWebSocket() {
const url = server.wsServerAdress + "?userKey=" + this.userKey;
private createWebSocket(url: string) {
const webSocket = new WebSocket(url);
webSocket.onopen = () => this.onWebSocketOpen(webSocket);
webSocket.onclose = () => this.onWebSocketClose(webSocket);
webSocket.onmessage = (event: MessageEvent) => this.onWebSocketMessage(webSocket, event);
webSocket.onmessage = (event: any) => this.onWebSocketMessage(webSocket, event);
webSocket.onerror = (error: any) => this.onWebSocketError(webSocket, error);
}
@ -34,21 +33,22 @@ export class RTMTWS extends EventEmitter2 implements RTMT {
if (!this.webSocket) return;
this.webSocket.onopen = () => { };
this.webSocket.onclose = () => { };
this.webSocket.onmessage = (event: MessageEvent) => { };
this.webSocket.onmessage = (event: any) => { };
this.webSocket.onerror = (error: any) => { };
this.webSocket = undefined;
}
public connectWebSocket(userKey: string) {
public connectWebSocket(url: string, userKey: string) {
this.setConnectionState("connecting");
this.userKey = userKey;
this.createWebSocket();
this.url = url;
this.createWebSocket(url);
}
private reconnectWebSocket() {
this.setConnectionState("reconnecting");
this.disposeWebSocket();
setTimeout(() => this.createWebSocket(), 1000);
setTimeout(() => this.createWebSocket(this.url), 1000);
}
protected onWebSocketOpen(webSocket: WebSocket) {
@ -59,7 +59,7 @@ export class RTMTWS extends EventEmitter2 implements RTMT {
this.emit("open");
}
protected onWebSocketMessage(webSocket: WebSocket, event: MessageEvent) {
protected onWebSocketMessage(webSocket: WebSocket, event: any) {
const { channel, message } = decode(event.data);
this.onMessage(channel, message);
}
@ -81,6 +81,7 @@ export class RTMTWS extends EventEmitter2 implements RTMT {
private heartbeat() {
clearTimeout(this.pingTimeout);
// @ts-ignore
this.pingTimeout = setTimeout(() => {
if (!this.webSocket) return;
console.log("(RTMT) WebSocket self closed");
@ -94,11 +95,11 @@ export class RTMTWS extends EventEmitter2 implements RTMT {
console.error("(RTMT) WebSocket is undefined");
return;
}
const data = encode(channel, message);
const data = encode({channel, message});
this.webSocket.send(data);
}
private onMessage(channel: string, message: Bytes) {
private onMessage(channel: string, message: Object) {
if (channel === channel_ping) {
this.heartbeat();
this.sendMessage(channel_pong, {});
@ -108,7 +109,7 @@ export class RTMTWS extends EventEmitter2 implements RTMT {
this.emit(MESSAGE_CHANNEL_PREFIX + channel, message);
}
public on(event: RtmtEventTypes, callback: (...value: any[]) => void): Listener | this {
public on(event: RtmtEventTypes, callback: (...value: any[]) => void): this {
return super.on(event, callback);
}
@ -126,6 +127,7 @@ export class RTMTWS extends EventEmitter2 implements RTMT {
public dispose() {
this.disposeWebSocket();
this.removeAllListeners();
// TODO
//this.removeAllListeners();
}
}

View File

@ -0,0 +1,15 @@
export type Message = {
channel: string,
message: Object,
}
export function encode(message: Message) {
return JSON.stringify({
channel : message.channel,
message : message.message
});
}
export function decode(bytes: string): Message {
return JSON.parse(bytes);
}

3
core/src/rtmt/index.ts Normal file
View File

@ -0,0 +1,3 @@
export * from './client/rtmt'
export * from './client/rtmt_websocket'
export * from './channel_names'

View File

@ -2842,6 +2842,11 @@ throat@^6.0.1:
resolved "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz"
integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==
tiny-emitter@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
tmpl@1.0.5:
version "1.0.5"
resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz"

View File

@ -10,14 +10,14 @@ import GamePage from './routes/GamePage';
import Home from './routes/Home';
import { initContext } from './context/context';
import { RTMTWS } from './rtmt/rtmt_websocket';
import { RTMTWS, ConnectionState } from '@mancala/core';
import { getColorByBrightness } from './util/ColorUtil';
import { Theme } from './theme/Theme';
import LobyPage from './routes/LobyPage';
import PrivacyPage from './routes/PrivacyPage';
import swal from 'sweetalert';
import { ConnectionState } from './rtmt/rtmt';
import Util from './util/Util';
import { server } from './const/config';
const context = initContext();
@ -39,7 +39,8 @@ const MancalaApp: FunctionComponent = () => {
const rtmt = context.rtmt as RTMTWS;
rtmt.on("error", onConnectionError);
rtmt.on("connectionchange", onConnectionChange)
rtmt.connectWebSocket(userKey)
const url = server.wsServerAdress + "?userKey=" + userKey;
rtmt.connectWebSocket(url, userKey)
return rtmt;
}

View File

@ -1,7 +1,6 @@
import { server } from "../const/config";
import { Texts, TrTr } from "../const/texts";
import { RTMT } from "../rtmt/rtmt";
import { RTMTWS } from "../rtmt/rtmt_websocket";
import { RTMT, RTMTWS } from "@mancala/core";
import { HttpServiceImpl } from "../service/HttpService";
import { GameStore, GameStoreImpl } from "../store/GameStore";
import { UserKeyStore, UserKeyStoreImpl } from "../store/KeyStore";

View File

@ -1,12 +0,0 @@
import { Bytes } from "./rtmt"
const textEncoder = new TextEncoder()
const textDecoder = new TextDecoder("utf-8")
export function encodeText(text : string) {
const bytes = textEncoder.encode(text)
return bytes
}
export function decodeText(bytes : Bytes) {
return textDecoder.decode(bytes)
}

View File

@ -1,20 +0,0 @@
import { decodeText, encodeText } from "./byte_util";
import { Bytes } from "./rtmt";
const headerLenght = 4
//
// channel is string, message is byte array
//
export function encode(channel : string, message : Object) {
return JSON.stringify({
channel,
message
})
}
//
// return { channel : string, message : byte array}
//
export function decode(bytes : string) {
return JSON.parse(bytes);
}

View File

@ -7,8 +7,7 @@ import { HomeScreen } from './screens/HomeScreen';
import LobyScreen from './screens/LobyScreen';
import { Context, initContext } from './context/context';
import { GameScreen } from './screens/GameScreen';
import { RTMTWS } from './rtmt/rtmt_websocket';
import { ConnectionState } from './rtmt/rtmt';
import { RTMTWS, ConnectionState } from '@mancala/core';
import { useTranslation } from 'react-i18next';
import Snackbar from 'react-native-snackbar';
import { NativeModules, I18nManager, Platform } from 'react-native'
@ -17,6 +16,7 @@ import { NativeModules, I18nManager, Platform } from 'react-native'
import 'react-native-get-random-values';
import HelpScreen from './screens/HelpScreen';
import { getColorByBrightness } from './util/ColorUtil';
import { server } from './const/config';
const Stack = createNativeStackNavigator<RootStackParamList>();
@ -57,7 +57,8 @@ function App() {
const rtmt = context.rtmt as RTMTWS;
rtmt.on("error", onConnectionError);
rtmt.on("connectionchange", onConnectionChange)
rtmt.connectWebSocket(userKey)
const url = server.wsServerAdress + "?userKey=" + userKey;
rtmt.connectWebSocket(url, userKey)
return rtmt;
}
const getTextByConnectionState = (context: Context, connectionState: ConnectionState): string => {

View File

@ -14,8 +14,6 @@ export const server: Server = useLocalServer ? {
wsServerAdress: "wss://mancala.segin.one",
};
export const RTMT_WS_PING_INTERVAL = 1000, RTMT_WS_PING_INTERVAL_BUFFER_TIME = 2000;
export const WEB_APP_URL = "https://playmancala.app";
export const PRIVAcY_URL = "https://playmancala.app/privacy";

View File

@ -1,6 +1,5 @@
import { server } from "../const/config";
import { RTMT } from "../rtmt/rtmt";
import { RTMTWS } from "../rtmt/rtmt_websocket";
import { RTMT, RTMTWS } from "@mancala/core";
import { HttpServiceImpl } from "../service/HttpService";
import { GameStore, GameStoreImpl } from "../store/GameStore";
import { UserKeyStore, UserKeyStoreImpl } from "../store/KeyStore";

View File

@ -1,12 +0,0 @@
import { Bytes } from "./rtmt"
const textEncoder = new TextEncoder()
const textDecoder = new TextDecoder("utf-8")
export function encodeText(text : string) {
const bytes = textEncoder.encode(text)
return bytes
}
export function decodeText(bytes : Bytes) {
return textDecoder.decode(bytes)
}

View File

@ -1,20 +0,0 @@
import { decodeText, encodeText } from "./byte_util";
import { Bytes } from "./rtmt";
const headerLenght = 4
//
// channel is string, message is byte array
//
export function encode(channel : string, message : Object) {
return JSON.stringify({
channel,
message
})
}
//
// return { channel : string, message : byte array}
//
export function decode(bytes : string) {
return JSON.parse(bytes);
}

View File

@ -7,6 +7,8 @@ export type ConnectionState = "none" | "connecting" | "error" | "connected" | "c
export type RtmtEventTypes = "open" | "close" | "connected" | "error" | "disconnected" | "message" | "connectionchange";
export const RTMT_WS_PING_INTERVAL = 1000, RTMT_WS_PING_INTERVAL_BUFFER_TIME = 2000;
export interface RTMT extends TinyEmitter {
get connectionState(): ConnectionState;
sendMessage: (channel: string, message: Object) => void;