Theia APIs——通过JSON-RPC进行通信
上一篇:Theia APIs——事件
通过JSON-PRC进行通信
概述
注册服务
import { ContainerModule } from 'inversify';
import { ConnectionHandler, JsonRpcConnectionHandler } from "../../messaging/common";
import { ILoggerServer, ILoggerClient } from '../../application/common/logger-protocol'; export const loggerServerModule = new ContainerModule(bind => {
bind(ConnectionHandler).toDynamicValue(ctx =>
new JsonRpcConnectionHandler<ILoggerClient>("/services/logger", client => {
const loggerServer = ctx.container.get<ILoggerServer>(ILoggerServer);
loggerServer.setClient(client);
return loggerServer;
})
).inSingletonScope()
});
我们来详细看一下:
import { ConnectionHandler, JsonRpcConnectionHandler } from "../../messaging/common";
import { MessageConnection } from "vscode-jsonrpc"; export const ConnectionHandler = Symbol('ConnectionHandler'); export interface ConnectionHandler {
readonly path: string;
onConnection(connection: MessageConnection): void;
}
import { ILoggerServer, ILoggerClient } from '../../application/common/logger-protocol';
文件logger-protocol.ts包含了服务器和客户端需要实现的接口。
bind<ConnectionHandler>(ConnectionHandler).toDynamicValue(ctx => {
constructor( @inject(ContributionProvider) @named(ConnectionHandler) protected readonly handlers: ContributionProvider<ConnectionHandler>) {
} onStart(server: http.Server): void {
for (const handler of this.handlers.getContributions()) {
const path = handler.path;
try {
createServerWebSocketConnection({
server,
path
}, connection => handler.onConnection(connection));
} catch (error) {
console.error(error)
}
}
}
new JsonRpcConnectionHandler<ILoggerClient>("/services/logger", client => {
我们来看看这个类的实现做了哪些事情:
export class JsonRpcConnectionHandler<T extends object> implements ConnectionHandler {
constructor(
readonly path: string,
readonly targetFactory: (proxy: JsonRpcProxy<T>) => any
) { } onConnection(connection: MessageConnection): void {
const factory = new JsonRpcProxyFactory<T>(this.path);
const proxy = factory.createProxy();
factory.target = this.targetFactory(proxy);
factory.listen(connection);
}
}
onConnection(connection: MessageConnection): void {
const factory = new JsonRpcProxyFactory<T>(this.path);
const proxy = factory.createProxy();
factory.target = this.targetFactory(proxy);
factory.listen(connection);
我们一行一行来看:
const factory = new JsonRpcProxyFactory<T>(this.path);
上面这一行在路径"/services/logger"上创建了一个JsonRpcProxy。
const proxy = factory.createProxy();
然后,我们从工厂创建了一个代理对象,它将使用ILoggerClient接口来调用JSON-RPC连接的另一端。
factory.target = this.targetFactory(proxy);
上面这一行将调用我们在参数中传递的函数,所以:
client => {
const loggerServer = ctx.container.get<ILoggerServer>(ILoggerServer);
loggerServer.setClient(client);
return loggerServer;
}
factory.listen(connection);
'/services/*': {
target: 'ws://localhost:3000',
ws: true
},
连接到服务
import { ContainerModule, Container } from 'inversify';
import { WebSocketConnectionProvider } from '../../messaging/browser/connection';
import { ILogger, LoggerFactory, LoggerOptions, Logger } from '../common/logger';
import { ILoggerServer } from '../common/logger-protocol';
import { LoggerWatcher } from '../common/logger-watcher'; export const loggerFrontendModule = new ContainerModule(bind => {
bind(ILogger).to(Logger).inSingletonScope();
bind(LoggerWatcher).toSelf().inSingletonScope();
bind(ILoggerServer).toDynamicValue(ctx => {
const loggerWatcher = ctx.container.get(LoggerWatcher);
const connection = ctx.container.get(WebSocketConnectionProvider);
return connection.createProxy<ILoggerServer>("/services/logger", loggerWatcher.getLoggerClient());
}).inSingletonScope();
});
其中最重要的几行:
bind(ILoggerServer).toDynamicValue(ctx => {
const loggerWatcher = ctx.container.get(LoggerWatcher);
const connection = ctx.container.get(WebSocketConnectionProvider);
return connection.createProxy<ILoggerServer>("/services/logger", loggerWatcher.getLoggerClient());
}).inSingletonScope();
我们一行一行来看:
const loggerWatcher = ctx.container.get(LoggerWatcher);
const connection = ctx.container.get(WebSocketConnectionProvider);
上面这一行获得了一个websocket连接,它将被用来创建一个代理。
return connection.createProxy<ILoggerServer>("/services/logger", loggerWatcher.getLoggerClient());
我们将一个本地对象作为第二个参数传入,用来处理来自远程对象的JSON-RPC消息。有时,本地对象依赖于代理,在代理实例化之前无法实例化。这种情况下,代理接口应该实现JsonRpcServer,而本地对象应该作为客户端来提供。
export type JsonRpcServer<Client> = Disposable & {
setClient(client: Client | undefined): void;
}; export interface ILoggerServer extends JsonRpcServery<ILoggerClient> {
// ...
} const serverProxy = connection.createProxy<ILoggerServer>("/services/logger");
const client = loggerWatcher.getLoggerClient();
serverProxy.setClient(client);
createProxy<T extends object>(path: string, target?: object, options?: WebSocketOptions): T {
const factory = new JsonRpcProxyFactory<T>(path, target);
this.listen(factory, options);
return factory.createProxy();
}
- 在路径"logger"上创建JsonRpc代理。
- 公开loggerWatcher.getLoggerClient()对象。
- 返回ILoggerServer类型的代理。
在示例的前端和后端加载模块
import { loggerServerModule } from 'theia-core/lib/application/node/logger-server-module';
然后将其载入到主容器。
container.load(loggerServerModule);
import { loggerFrontendModule } from 'theia-core/lib/application/browser/logger-frontend-module';
container.load(frontendLanguagesModule);
完成示例
Theia APIs——通过JSON-RPC进行通信的更多相关文章
- Theia APIs——Preferences
上一篇:Theia APIs——命令和快捷键 Preferences Theia有一个preference service,模块可以通过它来获取preference的值,提供默认的preference ...
- 測试JSON RPC远程调用(JSONclient)
#include <string> #include <iostream> #include <curl/curl.h> /* 标题:JSonclient Auth ...
- Theia APIs——事件
上一篇:Theia APIs——Preferences 事件 Theia中的事件或许会让你感到困惑,希望本节能阐述清楚. 来看下面的代码: (来自logger-watcher.ts) @injecta ...
- .net core consul grpc--系统服务RPC实现通信(一)
.net core grpc 系统服务实现通信(一) 现在系统都服务化,.net core 实现服务化的方式有很多,我们通过grpc实现客户端.服务端通信. grpc(https://grpc.io/ ...
- RPC 框架通信原理
RPC是指远程过程调用,也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据: ...
- [PHP 作为iOS后台Json格式HTTP通信及文件上传的实现]
1.数据库连接 configmysql.php <?php $q = mysql_connect("localhost:8889","root",&quo ...
- Unity3d使用json与javaserver通信
Unity3d使用json能够借助LitJson 下载LitJson,复制到Unity3d工作文件夹下 于是能够在代码中实现了 以下发送请求到server并解析 System.Collections. ...
- Theia APIs——命令和快捷键
上一篇:使用Theia——创建语言支持 命令和快捷键 Theia可以通过多种不同的方式进行扩展.命令允许packages提供可以被其它包调用的唯一命令,还可以向这些命令添加快捷键和上下文,使得它们只能 ...
- golang RPC通信读写超时设置
golang RPC通信中,有时候就怕读写hang住. 那是否可以设置读写超时呢? 1.方案一: 设置连接的读写超时 1.1 client RPC通信基于底层网络通信,可以通过设置connection ...
随机推荐
- 使用FormData格式上传图像并预览图片
前言 做项目时,遇到表单中图像需要跟表单一起提交,这样会造成后台没办法接收到图片.后面上网调查后,明白表单提交时是默认application/x-www-form-urlencoded格式,只接受键值 ...
- 箭头函数表达式和声名式函数表达式的区别以及 Function.prototype的bind, apply,call方法
箭头函数不能用做构造函数 箭头函数没有arguments参数 箭头函数没有自己的this,是从作用域链上取this,是与箭头函数定义的位置有关的,与执行时谁调用无关,所以用call,apply,bin ...
- jqLite
一.关于DOM导航的jqLite方法 children() 返回一组子元素.这个方法的jqLite实现不支持jQuery所提供的选择器特性 eq(index) 从一个元素集合中返回指定索引下的元素 f ...
- Java自动生成testcase
package com.citi.sl.tlc.services.tlc.collateralDataProcess.util; import java.io.BufferedWriter; impo ...
- Wunder Fund Round 2016 (Div. 1 + Div. 2 combined)
现在水平真的不够.只能够做做水题 A. Slime Combining 题意:就是给n个1给你.两个相同的数可以合并成一个数,比如说有两个相同的v,合并后的值就是v+1 思路:直接模拟栈 #inclu ...
- hsqldb使用
1 hsqldb介绍 HyperSQL DataBase 是一个现代的关系数据库管理软件,比较彻底遵从SQL:2008标准和JDBC4规范.支持SQL:2008标准所以的核心特性和很多的可选特性. H ...
- Vue 组件中的data数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Spring Cloud探路(一) Erueka服务器的建立
组件名:Netflix Eureka 作用:支撑微服务的自注册.自发现,提供负载均衡能力 开发环境使用IDEA 1.新建Eureka Server,新建maven项目,配置pom.xml <p ...
- H3C DHCP中继显示及维护
- 【30.43%】【codeforces 746C】Tram
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...