@viamrobotics/rpc
Advanced tools
Comparing version 0.1.9 to 0.1.10
{ | ||
"name": "@viamrobotics/rpc", | ||
"version": "0.1.9", | ||
"version": "0.1.10", | ||
"license": "MIT", | ||
@@ -5,0 +5,0 @@ "dependencies": { |
@@ -1,7 +0,16 @@ | ||
import { ClientChannel } from "./ClientChannel"; | ||
interface DialOptions { | ||
import { grpc } from "@improbable-eng/grpc-web"; | ||
export interface DialOptions { | ||
authEntity?: string; | ||
credentials?: Credentials; | ||
webrtcOptions?: DialWebRTCOptions; | ||
} | ||
export interface DialWebRTCOptions { | ||
disableTrickleICE: boolean; | ||
rtcConfig?: RTCConfiguration; | ||
} | ||
export declare function dial(signalingAddress: string, host: string, opts?: DialOptions): Promise<ClientChannel>; | ||
export {}; | ||
export interface Credentials { | ||
type: string; | ||
payload: string; | ||
} | ||
export declare function dialDirect(address: string, opts?: DialOptions): Promise<grpc.TransportFactory>; | ||
export declare function dialWebRTC(signalingAddress: string, host: string, opts?: DialOptions): Promise<grpc.TransportFactory>; |
130
src/dial.ts
import { grpc } from "@improbable-eng/grpc-web"; | ||
import { CallRequest, CallResponse, CallUpdateRequest, CallUpdateResponse, ICECandidate } from "proto/rpc/webrtc/v1/signaling_pb"; | ||
import { SignalingService } from "proto/rpc/webrtc/v1/signaling_pb_service"; | ||
import { AuthenticateRequest, AuthenticateResponse, Credentials as PBCredentials } from "proto/rpc/v1/auth_pb"; | ||
import { AuthService } from "proto/rpc/v1/auth_pb_service"; | ||
import { ClientChannel } from "./ClientChannel"; | ||
@@ -9,3 +11,9 @@ import { newPeerConnectionForClient } from "./peer"; | ||
interface DialOptions { | ||
export interface DialOptions { | ||
authEntity?: string; | ||
credentials?: Credentials; | ||
webrtcOptions?: DialWebRTCOptions; | ||
} | ||
export interface DialWebRTCOptions { | ||
disableTrickleICE: boolean; | ||
@@ -15,9 +23,108 @@ rtcConfig?: RTCConfiguration; | ||
export interface Credentials { | ||
type: string; | ||
payload: string; | ||
} | ||
export async function dialDirect(address: string, opts?: DialOptions): Promise<grpc.TransportFactory> { | ||
const defaultFactory = (opts: grpc.TransportOptions): grpc.Transport => { | ||
return grpc.CrossBrowserHttpTransport({ withCredentials: false })(opts); | ||
}; | ||
if (!opts?.credentials) { | ||
return defaultFactory; | ||
} | ||
return makeAuthenticatedTransportFactory(address, defaultFactory, opts); | ||
} | ||
async function makeAuthenticatedTransportFactory(address: string, defaultFactory: grpc.TransportFactory, opts?: DialOptions): Promise<grpc.TransportFactory> { | ||
let accessToken = ""; | ||
const getExtraMetadata = async (): Promise<grpc.Metadata> => { | ||
// TODO(https://github.com/viamrobotics/goutils/issues/13): handle expiration | ||
if (accessToken == "") { | ||
const request = new AuthenticateRequest(); | ||
request.setEntity(opts?.authEntity ? opts?.authEntity : address.replace(/^(.*:\/\/)/, '')); | ||
const creds = new PBCredentials(); | ||
creds.setType(opts?.credentials?.type!); | ||
creds.setPayload(opts?.credentials?.payload!); | ||
request.setCredentials(creds); | ||
let pResolve: (value: grpc.Metadata) => void; | ||
let pReject: (reason?: any) => void; | ||
let done = new Promise<grpc.Metadata>((resolve, reject) => { | ||
pResolve = resolve; | ||
pReject = reject; | ||
}); | ||
let thisAccessToken = ""; | ||
grpc.invoke(AuthService.Authenticate, { | ||
request: request, | ||
host: address, | ||
transport: defaultFactory, | ||
onMessage: (message: AuthenticateResponse) => { | ||
thisAccessToken = message.getAccessToken(); | ||
}, | ||
onEnd: (code: grpc.Code, msg: string | undefined, trailers: grpc.Metadata) => { | ||
if (code == grpc.Code.OK) { | ||
pResolve(md); | ||
} else { | ||
pReject(msg); | ||
} | ||
} | ||
}); | ||
await done; | ||
accessToken = thisAccessToken; | ||
} | ||
const md = new grpc.Metadata(); | ||
md.set("authorization", `Bearer ${accessToken}`); | ||
return md; | ||
} | ||
const extraMd = await getExtraMetadata(); | ||
return (opts: grpc.TransportOptions): grpc.Transport => { | ||
return new authenticatedTransport(opts, defaultFactory, extraMd); | ||
}; | ||
} | ||
class authenticatedTransport implements grpc.Transport { | ||
protected readonly opts: grpc.TransportOptions; | ||
protected readonly transport: grpc.Transport; | ||
protected readonly extraMetadata: grpc.Metadata; | ||
constructor(opts: grpc.TransportOptions, defaultFactory: grpc.TransportFactory, extraMetadata: grpc.Metadata) { | ||
this.opts = opts; | ||
this.extraMetadata = extraMetadata; | ||
this.transport = defaultFactory(opts); | ||
} | ||
public async start(metadata: grpc.Metadata) { | ||
this.extraMetadata.forEach((key, values) => { | ||
metadata.set(key, values); | ||
}); | ||
this.transport.start(metadata); | ||
} | ||
public sendMessage(msgBytes: Uint8Array) { | ||
this.transport.sendMessage(msgBytes); | ||
} | ||
public finishSend() { | ||
this.transport.finishSend(); | ||
} | ||
public cancel() { | ||
this.transport.cancel(); | ||
} | ||
} | ||
// TODO(https://github.com/viamrobotics/core/issues/111): figure out decent way to handle reconnect on connection termination | ||
export async function dial(signalingAddress: string, host: string, opts?: DialOptions): Promise<ClientChannel> { | ||
const { pc, dc } = await newPeerConnectionForClient(opts !== undefined && opts.disableTrickleICE, opts?.rtcConfig); | ||
export async function dialWebRTC(signalingAddress: string, host: string, opts?: DialOptions): Promise<grpc.TransportFactory> { | ||
const webrtcOpts = opts?.webrtcOptions; | ||
const { pc, dc } = await newPeerConnectionForClient(webrtcOpts !== undefined && webrtcOpts.disableTrickleICE, webrtcOpts?.rtcConfig); | ||
if (opts && opts.credentials && !opts.authEntity) { | ||
opts.authEntity = host; | ||
} | ||
const directTransport = await dialDirect(signalingAddress, opts); | ||
const client = grpc.client(SignalingService.Call, { | ||
host: signalingAddress | ||
}) | ||
host: signalingAddress, | ||
transport: directTransport, | ||
}); | ||
@@ -44,2 +151,3 @@ let uuid = ''; | ||
host: signalingAddress, | ||
transport: directTransport, | ||
onEnd: (output: grpc.UnaryOutput<CallUpdateResponse>) => { | ||
@@ -68,2 +176,3 @@ const { status, statusMessage, message } = output; | ||
host: signalingAddress, | ||
transport: directTransport, | ||
onEnd: (output: grpc.UnaryOutput<CallUpdateResponse>) => { | ||
@@ -86,3 +195,3 @@ const { status, statusMessage, message } = output; | ||
let exchangeDone = false; | ||
if (!opts?.disableTrickleICE) { | ||
if (!webrtcOpts?.disableTrickleICE) { | ||
// set up offer | ||
@@ -114,2 +223,3 @@ const offerDesc = await pc.createOffer(); | ||
host: signalingAddress, | ||
transport: directTransport, | ||
onEnd: (output: grpc.UnaryOutput<CallUpdateResponse>) => { | ||
@@ -147,3 +257,3 @@ const { status, statusMessage, message } = output; | ||
if (opts?.disableTrickleICE) { | ||
if (webrtcOpts?.disableTrickleICE) { | ||
exchangeDone = true; | ||
@@ -187,4 +297,4 @@ sendDone(); | ||
callRequest.setSdp(encodedSDP); | ||
if (opts && opts.disableTrickleICE) { | ||
callRequest.setDisableTrickle(opts.disableTrickleICE); | ||
if (webrtcOpts && webrtcOpts.disableTrickleICE) { | ||
callRequest.setDisableTrickle(webrtcOpts.disableTrickleICE); | ||
} | ||
@@ -197,3 +307,3 @@ client.send(callRequest); | ||
sendDone(); | ||
return cc; | ||
return cc.transportFactory(); | ||
} | ||
@@ -200,0 +310,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { dial } from "./dial"; | ||
export { dial }; | ||
import { dialDirect, dialWebRTC, Credentials } from "./dial"; | ||
export { dialDirect, dialWebRTC, Credentials, }; |
@@ -1,5 +0,7 @@ | ||
import { dial } from "./dial"; | ||
import { dialDirect, dialWebRTC, Credentials } from "./dial"; | ||
export { | ||
dial | ||
dialDirect, | ||
dialWebRTC, | ||
Credentials, | ||
}; |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2689818
3045