实现前后端通信
实现前后端的双向通信,我们需要依赖 BrowserModule
和 NodeModule
特殊的服务声明。
首先,需要定义一个双向通信的消息唯一通道,我们定义一个 ITodoConnectionServerPath
作为消息通道的唯一 ID,前后端的服务都通过这个通道进行消息分发。
// modules/todo/common/index.ts
export const ITodoConnectionServerPath = 'ITodoConnectionServerPath';
关联前后端服务
首先,需要在 TodoService
和 TodoNodeService
上继承 RPCService
。
// modules/todo/browser/todo.service.ts
@Injectable()
export class TodoService extends RPCService implements ITodoService { ... }
// modules/todo/node/todo.service.ts
@Injectable()
export class TodoNodeService extends RPCService implements ITodoNodeService { ... }
在双端的 TodoListModule
上进行关联。
关联前端服务
// modules/todo/browser/index.ts
import { Provider, Injectable } from '@opensumi/di';
import { BrowserModule } from '@opensumi/ide-core-browser';
import { TodoContribution } from './todo.contribution';
import { TodoService } from './todo.service';
import { ITodoConnectionServerPath, ITodoService } from '../common';
@Injectable()
export class TodoListModule extends BrowserModule {
providers: Provider[] = [
{
token: ITodoService,
useClass: TodoService
},
TodoContribution
];
backServices = [
{
servicePath: ITodoConnectionServerPath, // 双端通信通道唯一路径
clientToken: ITodoService // 关联前端服务
}
];
}
关联后端服务
// modules/todo/node/index.ts
import { Provider, Injectable } from '@opensumi/di';
import { NodeModule } from '@opensumi/ide-core-node';
import { ITodoNodeService, ITodoConnectionServerPath } from '../common';
import { TodoNodeService } from './todo.service';
@Injectable()
export class TodoListModule extends NodeModule {
providers: Provider[] = [
{
token: ITodoNodeService,
useClass: TodoNodeService
}
];
backServices = [
{
servicePath: ITodoConnectionServerPath, // 双端通信通道唯一路径
token: ITodoNodeService // 关联后端服务
}
];
}
实现前后端服务
本案例实现了,在 Todo 项点击的同时,传递消息到后端服务,后端服务在接收到消息时,重新组织消息内容后回传给前端进行消息展示。核心实现如下:
前端服务展示消息时同时通知到后端服务。
// modules/todo/browser/todo.service.ts
@Injectable()
export class TodoService extends RPCService implements ITodoService {
...
@Autowired(ITodoConnectionServerPath)
private todoNodeService: ITodoNodeService;
// 展示消息时调用后端服务
showMessage = (message: string) => {
this.messageService.info(message);
this.todoNodeService.showMessage(message);
};
// 接收后端消息
onMessage = (message: string) => {
this.messageService.info(message);
};
...
}
后端服务接收到消息后回传到前端服务。
// modules/todo/node/todo.service.ts
import { Injectable } from '@opensumi/di';
import { ITodoNodeService } from '../common';
import { RPCService } from '@opensumi/ide-connection';
@Injectable()
export class TodoNodeService extends RPCService implements ITodoNodeService {
showMessage = (message: string) => {
// 这里的 this.rpcClient![0] 可以直接获取到通信通道下的 proxy 实例
this.rpcClient![0].onMessage(`I got you message, echo again. ${message}`);
};
}
效果展示
自此,我们便完成了整个案例的完整教学。