MM-61991 Show server hostname in about modal (#29413)
This introduces a new entry in the `Main Menu -> About` modal with the hostname of the currently connected websocket. This will be used to aid debugging issues in clustered environments by showing which node in the cluster is servicing requests for a particular websocket. This information is only visible in self-managed instances. It will not be visible on cloud instances.
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
59b8532a89
Коммит
3224e0d3a2
@@ -11,6 +11,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -776,6 +777,15 @@ func (wc *WebConn) createHelloMessage() *model.WebSocketEvent {
|
|||||||
wc.Platform.ClientConfigHash(),
|
wc.Platform.ClientConfigHash(),
|
||||||
ee))
|
ee))
|
||||||
msg.Add("connection_id", wc.connectionID.Load())
|
msg.Add("connection_id", wc.connectionID.Load())
|
||||||
|
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
wc.Platform.logger.Error("Could not get hostname", mlog.Err(err))
|
||||||
|
// return without the hostname in the message
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.Add("server_hostname", hostname)
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1313,6 +1313,7 @@ export function handleStatusChangedEvent(msg) {
|
|||||||
function handleHelloEvent(msg) {
|
function handleHelloEvent(msg) {
|
||||||
dispatch(setServerVersion(msg.data.server_version));
|
dispatch(setServerVersion(msg.data.server_version));
|
||||||
dispatch(setConnectionId(msg.data.connection_id));
|
dispatch(setConnectionId(msg.data.connection_id));
|
||||||
|
dispatch(setServerHostname(msg.data.server_hostname));
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleReactionAddedEvent(msg) {
|
function handleReactionAddedEvent(msg) {
|
||||||
@@ -1333,6 +1334,13 @@ function setConnectionId(connectionId) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setServerHostname(serverHostname) {
|
||||||
|
return {
|
||||||
|
type: GeneralTypes.SET_SERVER_HOSTNAME,
|
||||||
|
payload: {serverHostname},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function handleAddEmoji(msg) {
|
function handleAddEmoji(msg) {
|
||||||
const data = JSON.parse(msg.data.emoji);
|
const data = JSON.parse(msg.data.emoji);
|
||||||
|
|
||||||
|
|||||||
@@ -25,11 +25,19 @@ describe('components/AboutBuildModal', () => {
|
|||||||
|
|
||||||
let config: Partial<ClientConfig> = {};
|
let config: Partial<ClientConfig> = {};
|
||||||
let license: ClientLicense = {};
|
let license: ClientLicense = {};
|
||||||
|
let socketStatus = {
|
||||||
|
connected: false,
|
||||||
|
serverHostname: '',
|
||||||
|
};
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
global.Date = RealDate;
|
global.Date = RealDate;
|
||||||
config = {};
|
config = {};
|
||||||
license = {};
|
license = {};
|
||||||
|
socketStatus = {
|
||||||
|
connected: false,
|
||||||
|
serverHostname: '',
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -51,10 +59,14 @@ describe('components/AboutBuildModal', () => {
|
|||||||
IsLicensed: 'true',
|
IsLicensed: 'true',
|
||||||
Company: 'Mattermost Inc',
|
Company: 'Mattermost Inc',
|
||||||
};
|
};
|
||||||
|
socketStatus = {
|
||||||
|
connected: true,
|
||||||
|
serverHostname: 'mock.localhost',
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should match snapshot for enterprise edition', () => {
|
test('should match snapshot for enterprise edition', () => {
|
||||||
renderAboutBuildModal({config, license});
|
renderAboutBuildModal({config, license, socketStatus});
|
||||||
expect(screen.getByTestId('aboutModalVersion')).toHaveTextContent('Mattermost Version: 3.6.0');
|
expect(screen.getByTestId('aboutModalVersion')).toHaveTextContent('Mattermost Version: 3.6.0');
|
||||||
expect(screen.getByTestId('aboutModalDBVersionString')).toHaveTextContent('Database Schema Version: 77');
|
expect(screen.getByTestId('aboutModalDBVersionString')).toHaveTextContent('Database Schema Version: 77');
|
||||||
expect(screen.getByTestId('aboutModalBuildNumber')).toHaveTextContent('Build Number: 123456');
|
expect(screen.getByTestId('aboutModalBuildNumber')).toHaveTextContent('Build Number: 123456');
|
||||||
@@ -62,6 +74,7 @@ describe('components/AboutBuildModal', () => {
|
|||||||
expect(screen.getByText('Modern communication from behind your firewall.')).toBeInTheDocument();
|
expect(screen.getByText('Modern communication from behind your firewall.')).toBeInTheDocument();
|
||||||
expect(screen.getByRole('link', {name: 'mattermost.com'})).toHaveAttribute('href', 'https://mattermost.com/?utm_source=mattermost&utm_medium=in-product&utm_content=about_build_modal&uid=&sid=');
|
expect(screen.getByRole('link', {name: 'mattermost.com'})).toHaveAttribute('href', 'https://mattermost.com/?utm_source=mattermost&utm_medium=in-product&utm_content=about_build_modal&uid=&sid=');
|
||||||
expect(screen.getByText('EE Build Hash: 0123456789abcdef', {exact: false})).toBeInTheDocument();
|
expect(screen.getByText('EE Build Hash: 0123456789abcdef', {exact: false})).toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('Hostname: mock.localhost', {exact: false})).toBeInTheDocument();
|
||||||
|
|
||||||
expect(screen.getByRole('link', {name: 'server'})).toHaveAttribute('href', 'https://github.com/mattermost/mattermost-server/blob/master/NOTICE.txt');
|
expect(screen.getByRole('link', {name: 'server'})).toHaveAttribute('href', 'https://github.com/mattermost/mattermost-server/blob/master/NOTICE.txt');
|
||||||
expect(screen.getByRole('link', {name: 'desktop'})).toHaveAttribute('href', 'https://github.com/mattermost/desktop/blob/master/NOTICE.txt');
|
expect(screen.getByRole('link', {name: 'desktop'})).toHaveAttribute('href', 'https://github.com/mattermost/desktop/blob/master/NOTICE.txt');
|
||||||
@@ -75,7 +88,7 @@ describe('components/AboutBuildModal', () => {
|
|||||||
BuildHashEnterprise: '',
|
BuildHashEnterprise: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
renderAboutBuildModal({config: teamConfig, license: {}});
|
renderAboutBuildModal({config: teamConfig, license: {}, socketStatus: {connected: false}});
|
||||||
expect(screen.getByTestId('aboutModalVersion')).toHaveTextContent('Mattermost Version: 3.6.0');
|
expect(screen.getByTestId('aboutModalVersion')).toHaveTextContent('Mattermost Version: 3.6.0');
|
||||||
expect(screen.getByTestId('aboutModalDBVersionString')).toHaveTextContent('Database Schema Version: 77');
|
expect(screen.getByTestId('aboutModalDBVersionString')).toHaveTextContent('Database Schema Version: 77');
|
||||||
expect(screen.getByTestId('aboutModalBuildNumber')).toHaveTextContent('Build Number: 123456');
|
expect(screen.getByTestId('aboutModalBuildNumber')).toHaveTextContent('Build Number: 123456');
|
||||||
@@ -83,6 +96,7 @@ describe('components/AboutBuildModal', () => {
|
|||||||
expect(screen.getByText('All your team communication in one place, instantly searchable and accessible anywhere.')).toBeInTheDocument();
|
expect(screen.getByText('All your team communication in one place, instantly searchable and accessible anywhere.')).toBeInTheDocument();
|
||||||
expect(screen.getByRole('link', {name: 'mattermost.com/community/'})).toHaveAttribute('href', 'https://mattermost.com/community/?utm_source=mattermost&utm_medium=in-product&utm_content=about_build_modal&uid=&sid=');
|
expect(screen.getByRole('link', {name: 'mattermost.com/community/'})).toHaveAttribute('href', 'https://mattermost.com/community/?utm_source=mattermost&utm_medium=in-product&utm_content=about_build_modal&uid=&sid=');
|
||||||
expect(screen.queryByText('EE Build Hash: 0123456789abcdef')).not.toBeInTheDocument();
|
expect(screen.queryByText('EE Build Hash: 0123456789abcdef')).not.toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('Hostname: disconnected', {exact: false})).toBeInTheDocument();
|
||||||
|
|
||||||
expect(screen.getByRole('link', {name: 'server'})).toHaveAttribute('href', 'https://github.com/mattermost/mattermost-server/blob/master/NOTICE.txt');
|
expect(screen.getByRole('link', {name: 'server'})).toHaveAttribute('href', 'https://github.com/mattermost/mattermost-server/blob/master/NOTICE.txt');
|
||||||
expect(screen.getByRole('link', {name: 'desktop'})).toHaveAttribute('href', 'https://github.com/mattermost/desktop/blob/master/NOTICE.txt');
|
expect(screen.getByRole('link', {name: 'desktop'})).toHaveAttribute('href', 'https://github.com/mattermost/desktop/blob/master/NOTICE.txt');
|
||||||
@@ -123,7 +137,7 @@ describe('components/AboutBuildModal', () => {
|
|||||||
BuildNumber: 'dev',
|
BuildNumber: 'dev',
|
||||||
};
|
};
|
||||||
|
|
||||||
renderAboutBuildModal({config: sameBuildConfig, license: {}});
|
renderAboutBuildModal({config: sameBuildConfig, license: {}, socketStatus: {connected: true}});
|
||||||
|
|
||||||
expect(screen.getByTestId('aboutModalVersion')).toHaveTextContent('Mattermost Version: dev');
|
expect(screen.getByTestId('aboutModalVersion')).toHaveTextContent('Mattermost Version: dev');
|
||||||
expect(screen.getByTestId('aboutModalDBVersionString')).toHaveTextContent('Database Schema Version: 77');
|
expect(screen.getByTestId('aboutModalDBVersionString')).toHaveTextContent('Database Schema Version: 77');
|
||||||
@@ -132,6 +146,7 @@ describe('components/AboutBuildModal', () => {
|
|||||||
expect(screen.getByText('All your team communication in one place, instantly searchable and accessible anywhere.')).toBeInTheDocument();
|
expect(screen.getByText('All your team communication in one place, instantly searchable and accessible anywhere.')).toBeInTheDocument();
|
||||||
expect(screen.getByRole('link', {name: 'mattermost.com/community/'})).toHaveAttribute('href', 'https://mattermost.com/community/?utm_source=mattermost&utm_medium=in-product&utm_content=about_build_modal&uid=&sid=');
|
expect(screen.getByRole('link', {name: 'mattermost.com/community/'})).toHaveAttribute('href', 'https://mattermost.com/community/?utm_source=mattermost&utm_medium=in-product&utm_content=about_build_modal&uid=&sid=');
|
||||||
expect(screen.queryByText('EE Build Hash: 0123456789abcdef')).not.toBeInTheDocument();
|
expect(screen.queryByText('EE Build Hash: 0123456789abcdef')).not.toBeInTheDocument();
|
||||||
|
expect(screen.queryByText('Hostname: server did not provide hostname', {exact: false})).toBeInTheDocument();
|
||||||
|
|
||||||
expect(screen.getByRole('link', {name: 'server'})).toHaveAttribute('href', 'https://github.com/mattermost/mattermost-server/blob/master/NOTICE.txt');
|
expect(screen.getByRole('link', {name: 'server'})).toHaveAttribute('href', 'https://github.com/mattermost/mattermost-server/blob/master/NOTICE.txt');
|
||||||
expect(screen.getByRole('link', {name: 'desktop'})).toHaveAttribute('href', 'https://github.com/mattermost/desktop/blob/master/NOTICE.txt');
|
expect(screen.getByRole('link', {name: 'desktop'})).toHaveAttribute('href', 'https://github.com/mattermost/desktop/blob/master/NOTICE.txt');
|
||||||
@@ -158,6 +173,7 @@ describe('components/AboutBuildModal', () => {
|
|||||||
<AboutBuildModal
|
<AboutBuildModal
|
||||||
config={config}
|
config={config}
|
||||||
license={license}
|
license={license}
|
||||||
|
socketStatus={socketStatus}
|
||||||
onExited={onExited}
|
onExited={onExited}
|
||||||
/>,
|
/>,
|
||||||
state,
|
state,
|
||||||
@@ -185,6 +201,7 @@ describe('components/AboutBuildModal', () => {
|
|||||||
<AboutBuildModal
|
<AboutBuildModal
|
||||||
config={config}
|
config={config}
|
||||||
license={license}
|
license={license}
|
||||||
|
socketStatus={socketStatus}
|
||||||
onExited={jest.fn()}
|
onExited={jest.fn()}
|
||||||
/>,
|
/>,
|
||||||
state,
|
state,
|
||||||
@@ -207,6 +224,7 @@ describe('components/AboutBuildModal', () => {
|
|||||||
onExited,
|
onExited,
|
||||||
config,
|
config,
|
||||||
license,
|
license,
|
||||||
|
socketStatus,
|
||||||
...props,
|
...props,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,11 @@ import {AboutLinks} from 'utils/constants';
|
|||||||
|
|
||||||
import AboutBuildModalCloud from './about_build_modal_cloud/about_build_modal_cloud';
|
import AboutBuildModalCloud from './about_build_modal_cloud/about_build_modal_cloud';
|
||||||
|
|
||||||
|
type SocketStatus = {
|
||||||
|
connected: boolean;
|
||||||
|
serverHostname: string | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,6 +36,8 @@ type Props = {
|
|||||||
* Global license object
|
* Global license object
|
||||||
*/
|
*/
|
||||||
license: ClientLicense;
|
license: ClientLicense;
|
||||||
|
|
||||||
|
socketStatus: SocketStatus;
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
@@ -182,6 +189,48 @@ export default class AboutBuildModal extends React.PureComponent<Props, State> {
|
|||||||
|
|
||||||
const mmversion: string | undefined = config.BuildNumber === 'dev' ? config.BuildNumber : config.Version;
|
const mmversion: string | undefined = config.BuildNumber === 'dev' ? config.BuildNumber : config.Version;
|
||||||
|
|
||||||
|
let serverHostname;
|
||||||
|
if (!this.props.socketStatus.connected) {
|
||||||
|
serverHostname = (
|
||||||
|
<div>
|
||||||
|
<FormattedMessage
|
||||||
|
id='about.serverHostname'
|
||||||
|
defaultMessage='Hostname:'
|
||||||
|
/>
|
||||||
|
<Nbsp/>
|
||||||
|
<FormattedMessage
|
||||||
|
id='about.serverDisconnected'
|
||||||
|
defaultMessage='disconnected'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else if (this.props.socketStatus.serverHostname) {
|
||||||
|
serverHostname = (
|
||||||
|
<div>
|
||||||
|
<FormattedMessage
|
||||||
|
id='about.serverHostname'
|
||||||
|
defaultMessage='Hostname:'
|
||||||
|
/>
|
||||||
|
<Nbsp/>
|
||||||
|
{this.props.socketStatus.serverHostname}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
serverHostname = (
|
||||||
|
<div>
|
||||||
|
<FormattedMessage
|
||||||
|
id='about.serverHostname'
|
||||||
|
defaultMessage='Hostname:'
|
||||||
|
/>
|
||||||
|
<Nbsp/>
|
||||||
|
<FormattedMessage
|
||||||
|
id='about.serverUnknown'
|
||||||
|
defaultMessage='server did not provide hostname'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
dialogClassName='a11y__modal about-modal'
|
dialogClassName='a11y__modal about-modal'
|
||||||
@@ -246,6 +295,7 @@ export default class AboutBuildModal extends React.PureComponent<Props, State> {
|
|||||||
/>
|
/>
|
||||||
{'\u00a0' + config.SQLDriverName}
|
{'\u00a0' + config.SQLDriverName}
|
||||||
</div>
|
</div>
|
||||||
|
{serverHostname}
|
||||||
</div>
|
</div>
|
||||||
{licensee}
|
{licensee}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import {connect} from 'react-redux';
|
|||||||
|
|
||||||
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
|
import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general';
|
||||||
|
|
||||||
|
import {getSocketStatus} from 'selectors/views/websocket';
|
||||||
|
|
||||||
import type {GlobalState} from 'types/store';
|
import type {GlobalState} from 'types/store';
|
||||||
|
|
||||||
import AboutBuildModal from './about_build_modal';
|
import AboutBuildModal from './about_build_modal';
|
||||||
@@ -13,6 +15,7 @@ function mapStateToProps(state: GlobalState) {
|
|||||||
return {
|
return {
|
||||||
config: getConfig(state),
|
config: getConfig(state),
|
||||||
license: getLicense(state),
|
license: getLicense(state),
|
||||||
|
socketStatus: getSocketStatus(state),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ exports[`PostBodyAdditionalContent with a normal link Should render the plugin c
|
|||||||
"reconnectListeners": Set {},
|
"reconnectListeners": Set {},
|
||||||
"responseCallbacks": Object {},
|
"responseCallbacks": Object {},
|
||||||
"responseSequence": 1,
|
"responseSequence": 1,
|
||||||
|
"serverHostname": "",
|
||||||
"serverSequence": 0,
|
"serverSequence": 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,6 +164,7 @@ exports[`PostBodyAdditionalContent with a normal link Should render the plugin c
|
|||||||
"reconnectListeners": Set {},
|
"reconnectListeners": Set {},
|
||||||
"responseCallbacks": Object {},
|
"responseCallbacks": Object {},
|
||||||
"responseSequence": 1,
|
"responseSequence": 1,
|
||||||
|
"serverHostname": "",
|
||||||
"serverSequence": 0,
|
"serverSequence": 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ describe('ProductNoticesModal', () => {
|
|||||||
connectionId: '',
|
connectionId: '',
|
||||||
lastConnectAt: 1599760193593,
|
lastConnectAt: 1599760193593,
|
||||||
lastDisconnectAt: 0,
|
lastDisconnectAt: 0,
|
||||||
|
serverHostname: '',
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
getInProductNotices: jest.fn().mockResolvedValue({data: noticesData}),
|
getInProductNotices: jest.fn().mockResolvedValue({data: noticesData}),
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
"about.licensed": "Licensed to:",
|
"about.licensed": "Licensed to:",
|
||||||
"about.notice": "Mattermost is made possible by the open source software used in our <linkServer>server</linkServer>, <linkDesktop>desktop</linkDesktop> and <linkMobile>mobile</linkMobile> apps.",
|
"about.notice": "Mattermost is made possible by the open source software used in our <linkServer>server</linkServer>, <linkDesktop>desktop</linkDesktop> and <linkMobile>mobile</linkMobile> apps.",
|
||||||
"about.privacy": "Privacy Policy",
|
"about.privacy": "Privacy Policy",
|
||||||
|
"about.serverDisconnected": "disconnected",
|
||||||
|
"about.serverHostname": "Hostname:",
|
||||||
|
"about.serverUnknown": "server did not provide hostname",
|
||||||
"about.teamEditionLearn": "Join the Mattermost community at ",
|
"about.teamEditionLearn": "Join the Mattermost community at ",
|
||||||
"about.teamEditionSt": "All your team communication in one place, instantly searchable and accessible anywhere.",
|
"about.teamEditionSt": "All your team communication in one place, instantly searchable and accessible anywhere.",
|
||||||
"about.teamEditiont0": "Team Edition",
|
"about.teamEditiont0": "Team Edition",
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ export default keyMirror({
|
|||||||
WEBSOCKET_FAILURE: null,
|
WEBSOCKET_FAILURE: null,
|
||||||
WEBSOCKET_CLOSED: null,
|
WEBSOCKET_CLOSED: null,
|
||||||
SET_CONNECTION_ID: null,
|
SET_CONNECTION_ID: null,
|
||||||
|
SET_SERVER_HOSTNAME: null,
|
||||||
|
|
||||||
SET_CONFIG_AND_LICENSE: null,
|
SET_CONFIG_AND_LICENSE: null,
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ function getInitialState() {
|
|||||||
lastConnectAt: 0,
|
lastConnectAt: 0,
|
||||||
lastDisconnectAt: 0,
|
lastDisconnectAt: 0,
|
||||||
connectionId: '',
|
connectionId: '',
|
||||||
|
serverHostname: '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,6 +27,7 @@ export default function reducer(state = getInitialState(), action: AnyAction) {
|
|||||||
...state,
|
...state,
|
||||||
connected: false,
|
connected: false,
|
||||||
lastDisconnectAt: action.timestamp,
|
lastDisconnectAt: action.timestamp,
|
||||||
|
serverHostname: '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,5 +46,12 @@ export default function reducer(state = getInitialState(), action: AnyAction) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action.type === GeneralTypes.SET_SERVER_HOSTNAME) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
serverHostname: action.payload.serverHostname,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -318,6 +318,7 @@ const state: GlobalState = {
|
|||||||
lastConnectAt: 0,
|
lastConnectAt: 0,
|
||||||
lastDisconnectAt: 0,
|
lastDisconnectAt: 0,
|
||||||
connectionId: '',
|
connectionId: '',
|
||||||
|
serverHostname: '',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
export default state;
|
export default state;
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ exports[`plugins/Pluggable should match snapshot with extended component 1`] = `
|
|||||||
"reconnectListeners": Set {},
|
"reconnectListeners": Set {},
|
||||||
"responseCallbacks": Object {},
|
"responseCallbacks": Object {},
|
||||||
"responseSequence": 1,
|
"responseSequence": 1,
|
||||||
|
"serverHostname": "",
|
||||||
"serverSequence": 0,
|
"serverSequence": 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -262,6 +263,7 @@ exports[`plugins/Pluggable should match snapshot with extended component with pl
|
|||||||
"reconnectListeners": Set {},
|
"reconnectListeners": Set {},
|
||||||
"responseCallbacks": Object {},
|
"responseCallbacks": Object {},
|
||||||
"responseSequence": 1,
|
"responseSequence": 1,
|
||||||
|
"serverHostname": "",
|
||||||
"serverSequence": 0,
|
"serverSequence": 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -534,6 +536,7 @@ exports[`plugins/Pluggable should match snapshot with null pluggableId 1`] = `
|
|||||||
"reconnectListeners": Set {},
|
"reconnectListeners": Set {},
|
||||||
"responseCallbacks": Object {},
|
"responseCallbacks": Object {},
|
||||||
"responseSequence": 1,
|
"responseSequence": 1,
|
||||||
|
"serverHostname": "",
|
||||||
"serverSequence": 0,
|
"serverSequence": 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -673,6 +676,7 @@ exports[`plugins/Pluggable should match snapshot with valid pluggableId 1`] = `
|
|||||||
"reconnectListeners": Set {},
|
"reconnectListeners": Set {},
|
||||||
"responseCallbacks": Object {},
|
"responseCallbacks": Object {},
|
||||||
"responseSequence": 1,
|
"responseSequence": 1,
|
||||||
|
"serverHostname": "",
|
||||||
"serverSequence": 0,
|
"serverSequence": 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1903,6 +1903,7 @@
|
|||||||
|
|
||||||
.about-modal__content {
|
.about-modal__content {
|
||||||
display: block;
|
display: block;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
.about-modal__hash {
|
.about-modal__hash {
|
||||||
|
|||||||
@@ -57,6 +57,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
padding: 1em 0 3em;
|
padding: 1em 0 3em;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
.about-modal__copyright {
|
.about-modal__copyright {
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ export default class WebSocketClient {
|
|||||||
private closeListeners = new Set<CloseListener>();
|
private closeListeners = new Set<CloseListener>();
|
||||||
|
|
||||||
private connectionId: string | null;
|
private connectionId: string | null;
|
||||||
|
private serverHostname: string | null;
|
||||||
private postedAck: boolean;
|
private postedAck: boolean;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -78,6 +79,7 @@ export default class WebSocketClient {
|
|||||||
this.connectFailCount = 0;
|
this.connectFailCount = 0;
|
||||||
this.responseCallbacks = {};
|
this.responseCallbacks = {};
|
||||||
this.connectionId = '';
|
this.connectionId = '';
|
||||||
|
this.serverHostname = '';
|
||||||
this.postedAck = false;
|
this.postedAck = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,6 +212,9 @@ export default class WebSocketClient {
|
|||||||
// If it's a fresh connection, we have to set the connectionId regardless.
|
// If it's a fresh connection, we have to set the connectionId regardless.
|
||||||
// And if it's an existing connection, setting it again is harmless, and keeps the code simple.
|
// And if it's an existing connection, setting it again is harmless, and keeps the code simple.
|
||||||
this.connectionId = msg.data.connection_id;
|
this.connectionId = msg.data.connection_id;
|
||||||
|
|
||||||
|
// Also update the server hostname
|
||||||
|
this.serverHostname = msg.data.server_hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we check for sequence number, and if it does not match,
|
// Now we check for sequence number, and if it does not match,
|
||||||
|
|||||||
@@ -94,5 +94,6 @@ export type GlobalState = {
|
|||||||
lastConnectAt: number;
|
lastConnectAt: number;
|
||||||
lastDisconnectAt: number;
|
lastDisconnectAt: number;
|
||||||
connectionId: string;
|
connectionId: string;
|
||||||
|
serverHostname: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user