diff --git a/packages/core/src/browser/messaging/ws-connection-source.ts b/packages/core/src/browser/messaging/ws-connection-source.ts index e1105fdd1bc7a..2ed841595c954 100644 --- a/packages/core/src/browser/messaging/ws-connection-source.ts +++ b/packages/core/src/browser/messaging/ws-connection-source.ts @@ -20,7 +20,7 @@ import { Socket, io } from 'socket.io-client'; import { Endpoint } from '../endpoint'; import { ForwardingChannel } from '../../common/message-rpc/channel'; import { Uint8ArrayReadBuffer, Uint8ArrayWriteBuffer } from '../../common/message-rpc/uint8-array-message-buffer'; -import { inject, injectable } from 'inversify'; +import { inject, injectable, postConstruct } from 'inversify'; import { FrontendIdProvider } from './frontend-id-provider'; import { FrontendApplicationConfigProvider } from '../frontend-application-config-provider'; import { SocketWriteBuffer } from '../../common/messaging/socket-write-buffer'; @@ -35,7 +35,7 @@ export class WebsocketConnectionSource implements ConnectionSource { private readonly writeBuffer = new SocketWriteBuffer(); - protected readonly _socket: Socket; + private _socket: Socket; get socket(): Socket { return this._socket; } @@ -63,9 +63,12 @@ export class WebsocketConnectionSource implements ConnectionSource { } constructor() { + } + + @postConstruct() + openSocket(): void { const url = this.createWebSocketUrl(servicesPath); this._socket = this.createWebSocket(url); - this._socket.connect(); this._socket.on('connect', () => { this.onSocketDidOpenEmitter.fire(); @@ -81,6 +84,7 @@ export class WebsocketConnectionSource implements ConnectionSource { this.currentChannel.onErrorEmitter.fire(reason); }; }); + this._socket.connect(); } protected handleSocketConnected(): void { diff --git a/packages/core/src/node/messaging/test/test-web-socket-channel.ts b/packages/core/src/node/messaging/test/test-web-socket-channel.ts index bc4e16fc532cc..a21ea02a5675b 100644 --- a/packages/core/src/node/messaging/test/test-web-socket-channel.ts +++ b/packages/core/src/node/messaging/test/test-web-socket-channel.ts @@ -1,3 +1,4 @@ +/* eslint-disable @theia/runtime-import-check */ // ***************************************************************************** // Copyright (C) 2018 TypeFox and others. // @@ -17,25 +18,44 @@ import * as http from 'http'; import * as https from 'https'; import { AddressInfo } from 'net'; -import { io } from 'socket.io-client'; -import { Channel, ChannelMultiplexer } from '../../../common/message-rpc/channel'; import { servicesPath } from '../../../common'; -import { WebSocketChannel } from '../../../common/messaging/web-socket-channel'; +import { WebsocketConnectionSource } from '../../../browser/messaging/ws-connection-source'; +import { Container, inject } from 'inversify'; +import { RemoteConnectionProvider, ServiceConnectionProvider } from '../../../browser/messaging/service-connection-provider'; +import { messagingFrontendModule } from '../../../browser/messaging/messaging-frontend-module'; +import { Socket, io } from 'socket.io-client'; + +const websocketUrl = Symbol('testWebsocketUrl'); +class TestWebsocketConnectionSource extends WebsocketConnectionSource { + @inject(websocketUrl) + readonly websocketUrl: string; + + protected override createWebSocketUrl(path: string): string { + return this.websocketUrl; + } + + protected override createWebSocket(url: string): Socket { + return io(url); + } +} export class TestWebSocketChannelSetup { - public readonly multiplexer: ChannelMultiplexer; - public readonly channel: Channel; + public readonly connectionProvider: ServiceConnectionProvider; constructor({ server, path }: { server: http.Server | https.Server, path: string }) { - const socket = io(`ws://localhost:${(server.address() as AddressInfo).port}${servicesPath}`); - this.channel = new WebSocketChannel(socket); - this.multiplexer = new ChannelMultiplexer(this.channel); - socket.on('connect', () => { - this.multiplexer.open(path); - }); - socket.connect(); + const address = (server.address() as AddressInfo); + const url = `ws://${address.address}:${address.port}${servicesPath}`; + this.connectionProvider = this.createConnectionProvider(url); + } + + protected createConnectionProvider(socketUrl: string): ServiceConnectionProvider { + const container = new Container(); + container.bind(websocketUrl).toConstantValue(socketUrl); + container.load(messagingFrontendModule); + container.rebind(WebsocketConnectionSource).to(TestWebsocketConnectionSource); + return container.get(RemoteConnectionProvider); } } diff --git a/packages/task/src/node/task-server.slow-spec.ts b/packages/task/src/node/task-server.slow-spec.ts index 03749c9d2f2aa..4c49bd6e8d272 100644 --- a/packages/task/src/node/task-server.slow-spec.ts +++ b/packages/task/src/node/task-server.slow-spec.ts @@ -72,7 +72,7 @@ describe('Task server / back-end', function (): void { taskServer = testContainer.get(TaskServer); taskServer.setClient(taskWatcher.getTaskClient()); backend = testContainer.get(BackendApplication); - server = await backend.start(); + server = await backend.start(3000, 'localhost'); }); afterEach(async () => { @@ -104,11 +104,11 @@ describe('Task server / back-end', function (): void { await new Promise((resolve, reject) => { const setup = new TestWebSocketChannelSetup({ server, path: `${terminalsPath}/${terminalId}` }); const stringBuffer = new StringBufferingStream(); - setup.multiplexer.onDidOpenChannel(event => { - event.channel.onMessage(e => stringBuffer.push(e().readString())); - event.channel.onError(reject); - event.channel.onClose(() => reject(new Error('Channel has been closed'))); - }); + setup.connectionProvider.listen(`${terminalsPath}/${terminalId}`, (path, channel) => { + channel.onMessage(e => stringBuffer.push(e().readString())); + channel.onError(reject); + channel.onClose(() => reject(new Error('Channel has been closed'))); + }, false); stringBuffer.onData(currentMessage => { // Instead of waiting for one message from the terminal, we wait for several ones as the very first message can be something unexpected. // For instance: `nvm is not compatible with the \"PREFIX\" environment variable: currently set to \"/usr/local\"\r\n` diff --git a/packages/terminal/src/node/terminal-backend-contribution.slow-spec.ts b/packages/terminal/src/node/terminal-backend-contribution.slow-spec.ts index cf9defadd94a9..c9b3b6316549f 100644 --- a/packages/terminal/src/node/terminal-backend-contribution.slow-spec.ts +++ b/packages/terminal/src/node/terminal-backend-contribution.slow-spec.ts @@ -32,7 +32,7 @@ describe('Terminal Backend Contribution', function (): void { const container = createTerminalTestContainer(); const application = container.get(BackendApplication); shellTerminalServer = container.get(IShellTerminalServer); - server = await application.start(); + server = await application.start(3000, 'localhost'); }); afterEach(() => { @@ -46,16 +46,16 @@ describe('Terminal Backend Contribution', function (): void { const terminalId = await shellTerminalServer.create({}); await new Promise((resolve, reject) => { const path = `${terminalsPath}/${terminalId}`; - const { channel, multiplexer } = new TestWebSocketChannelSetup({ server, path }); - channel.onError(reject); - channel.onClose(event => reject(new Error(`channel is closed with '${event.code}' code and '${event.reason}' reason}`))); + const { connectionProvider } = new TestWebSocketChannelSetup({ server, path }); - multiplexer.onDidOpenChannel(event => { - if (event.id === path) { + connectionProvider.listen(path, (path2, channel) => { + channel.onError(reject); + channel.onClose(event => reject(new Error(`channel is closed with '${event.code}' code and '${event.reason}' reason}`))); + if (path2 === path) { resolve(); channel.close(); } - }); + }, false); }); });