Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9bdba97
Squashed commit of the following:
burdettadam Aug 16, 2021
791b740
formatting
burdettadam Aug 16, 2021
c468e33
Update packages/core/src/modules/routing/RecipientModule.ts
burdettadam Aug 16, 2021
15d517e
Update packages/core/src/modules/routing/RecipientModule.ts
burdettadam Aug 16, 2021
3e6da2f
Update packages/core/src/modules/routing/RecipientModule.ts
burdettadam Aug 16, 2021
b17d85a
feat: created service retrieval with priority sorting
JamesKEbert Aug 14, 2021
4f1da15
add get protocal scheme on service class
burdettadam Aug 17, 2021
267dbab
priority is ws, wss for mediation
burdettadam Aug 18, 2021
68f9090
feat: altered mediation recipient sending logic
JamesKEbert Aug 20, 2021
c959cdc
chore: formatting
JamesKEbert Aug 20, 2021
bda647f
fix: add buffer as react native dependency for ws communciation
JamesKEbert Aug 21, 2021
f151915
chore: altered buffer import
JamesKEbert Aug 21, 2021
4ff41f0
chore: altered buffer import location
JamesKEbert Aug 21, 2021
b044b3d
Merge branch 'main' into transport-priority/recipient
JamesKEbert Aug 21, 2021
02cd324
chore: fixed core package version
JamesKEbert Aug 21, 2021
8a613c4
chore: fix buffer dependency
JamesKEbert Aug 26, 2021
0cc91a5
Merge branch 'main' into transport-priority/recipient
JamesKEbert Aug 26, 2021
5c98a5c
chore: import formatting
JamesKEbert Aug 26, 2021
f1ba083
fix: pass connectionId to allow for mediator websocket reopening
JamesKEbert Aug 26, 2021
f682344
chore: reverted openMediationWebsocket sending functionality, added t…
JamesKEbert Sep 9, 2021
bd05532
chore: formatting
JamesKEbert Sep 9, 2021
92548ae
Merge branch 'main' into transport-priority/recipient
JamesKEbert Sep 9, 2021
d4eaac6
fix: failing message sender tests
JamesKEbert Sep 9, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/setup-react-native.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
To start using Aries Framework JavaScript in React Native some platform specific dependencies are required.

1. Follow the [React Native Setup](https://reactnative.dev/docs/environment-setup) guide to set up your environment.
2. Add `@aries-framework/core` and `@aries-framework/react-native` to your project.
2. Add `@aries-framework/core`, `@aries-framework/react-native`, `react-native-fs`, and `react-native-get-random-values` to your project.

```bash
yarn add @aries-framework/core @aries-framework/react-native
yarn add @aries-framework/core @aries-framework/react-native react-native-fs react-native-get-random-values
```

3. Install [Libindy](https://github.com/hyperledger/indy-sdk) for iOS and Android:
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/agent/MessageSender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ export class MessageSender {
service,
senderKey: connection.verkey,
returnRoute: shouldUseReturnRoute,
connectionId: connection.id,
})
return
} catch (error) {
Expand Down Expand Up @@ -225,11 +226,13 @@ export class MessageSender {
service,
senderKey,
returnRoute,
connectionId,
}: {
message: AgentMessage
service: DidCommService
senderKey: string
returnRoute?: boolean
connectionId?: string
}) {
if (this.outboundTransports.length === 0) {
throw new AriesFrameworkError('Agent has no outbound transport!')
Expand All @@ -250,6 +253,7 @@ export class MessageSender {

const outboundPackage = await this.packMessage({ message, keys, endpoint: service.serviceEndpoint })
outboundPackage.endpoint = service.serviceEndpoint
outboundPackage.connectionId = connectionId
for (const transport of this.outboundTransports) {
if (transport.supportedSchemes.includes(service.protocolScheme)) {
await transport.sendMessage(outboundPackage)
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/agent/__tests__/MessageSender.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ describe('MessageSender', () => {
await messageSender.sendMessage(outboundMessage)

expect(sendMessageSpy).toHaveBeenCalledWith({
connectionId: 'test-123',
payload: wireMessage,
endpoint: firstDidCommService.serviceEndpoint,
responseRequested: false,
Expand All @@ -149,6 +150,7 @@ describe('MessageSender', () => {
await messageSender.sendMessage(outboundMessage)

expect(sendMessageSpy).toHaveBeenCalledWith({
connectionId: 'test-123',
payload: wireMessage,
endpoint: firstDidCommService.serviceEndpoint,
responseRequested: false,
Expand All @@ -164,6 +166,7 @@ describe('MessageSender', () => {
await messageSender.sendMessage(outboundMessage)

expect(sendMessageToServiceSpy).toHaveBeenCalledWith({
connectionId: 'test-123',
message: outboundMessage.payload,
senderKey: connection.verkey,
service: firstDidCommService,
Expand All @@ -184,6 +187,7 @@ describe('MessageSender', () => {
await messageSender.sendMessage(outboundMessage)

expect(sendMessageToServiceSpy).toHaveBeenNthCalledWith(2, {
connectionId: 'test-123',
message: outboundMessage.payload,
senderKey: connection.verkey,
service: secondDidCommService,
Expand Down
59 changes: 42 additions & 17 deletions packages/core/src/modules/routing/RecipientModule.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Logger } from '../../logger'
import type { OutboundWebSocketClosedEvent } from '../../transport'
import type { OutboundMessage } from '../../types'
import type { ConnectionRecord } from '../connections'
import type { MediationStateChangedEvent } from './RoutingEvents'
import type { MediationRecord } from './index'
Expand Down Expand Up @@ -73,6 +74,23 @@ export class RecipientModule {
}
}

private async sendMessage(outboundMessage: OutboundMessage) {
const { mediatorPickupStrategy } = this.agentConfig
const transportPriority =
mediatorPickupStrategy === MediatorPickupStrategy.Implicit
? { schemes: ['wss', 'ws'], restrictive: true }
: undefined

await this.messageSender.sendMessage(outboundMessage, {
transportPriority,
// TODO: add keepAlive: true to enforce through the public api
// we need to keep the socket alive. It already works this way, but would
// be good to make more explicit from the public facing API.
// This would also make it easier to change the internal API later on.
// keepAlive: true,
})
}

private async openMediationWebSocket(mediator: MediationRecord) {
const { message, connectionRecord } = await this.connectionService.createTrustPing(mediator.connectionId)

Expand All @@ -85,17 +103,21 @@ export class RecipientModule {
throw new AriesFrameworkError('Cannot open websocket to connection without websocket service endpoint')
}

await this.messageSender.sendMessage(createOutboundMessage(connectionRecord, message), {
transportPriority: {
schemes: websocketSchemes,
restrictive: true,
// TODO: add keepAlive: true to enforce through the public api
// we need to keep the socket alive. It already works this way, but would
// be good to make more explicit from the public facing API.
// This would also make it easier to change the internal API later on.
// keepAlive: true,
},
})
try {
await this.messageSender.sendMessage(createOutboundMessage(connectionRecord, message), {
transportPriority: {
schemes: websocketSchemes,
restrictive: true,
// TODO: add keepAlive: true to enforce through the public api
// we need to keep the socket alive. It already works this way, but would
// be good to make more explicit from the public facing API.
// This would also make it easier to change the internal API later on.
// keepAlive: true,
},
})
} catch (error) {
this.logger.warn('Unable to open websocket connection to mediator', { error })
}
Comment on lines +118 to +120
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we want to swallow this error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue that I ran into is that it will throw an error if you don't have internet access, etc. Which means that if you throw it, it won't be caught and will not be able to reconnect properly. As far as I saw at least. Happy to go about this a different way in the future if desired.

}

private async initiateImplicitPickup(mediator: MediationRecord) {
Expand All @@ -118,7 +140,10 @@ export class RecipientModule {
// Wait for interval time before reconnecting
delay(interval)
)
.subscribe(() => {
.subscribe(async () => {
this.logger.warn(
`Websocket connection to mediator with connectionId '${mediator.connectionId}' is closed, attempting to reconnect...`
)
this.openMediationWebSocket(mediator)
})

Expand Down Expand Up @@ -163,7 +188,7 @@ export class RecipientModule {

const batchPickupMessage = new BatchPickupMessage({ batchSize: 10 })
const outboundMessage = createOutboundMessage(mediatorConnection, batchPickupMessage)
await this.messageSender.sendMessage(outboundMessage)
await this.sendMessage(outboundMessage)
}

public async setDefaultMediator(mediatorRecord: MediationRecord) {
Expand All @@ -173,15 +198,15 @@ export class RecipientModule {
public async requestMediation(connection: ConnectionRecord): Promise<MediationRecord> {
const { mediationRecord, message } = await this.mediationRecipientService.createRequest(connection)
const outboundMessage = createOutboundMessage(connection, message)
await this.messageSender.sendMessage(outboundMessage)

await this.sendMessage(outboundMessage)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like we're conflating specific transport protocols with the implicit / explicit pickup strategy (I'm also to blame for this)

Do we always need to request mediation over websockets if we're using the implicit pickup strategy? I think not.

I'm fine with taking this approach for now, but would like to keep this in mind going forward. It closes some doors that I would like to keep open :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I think that we'll want to adjust this in the future, especially with pickup-protocol v2.

return mediationRecord
}

public async notifyKeylistUpdate(connection: ConnectionRecord, verkey: string) {
const message = this.mediationRecipientService.createKeylistUpdateMessage(verkey)
const outboundMessage = createOutboundMessage(connection, message)
const response = await this.messageSender.sendMessage(outboundMessage)
return response
await this.sendMessage(outboundMessage)
}

public async findByConnectionId(connectionId: string) {
Expand Down Expand Up @@ -230,7 +255,7 @@ export class RecipientModule {

// Send mediation request message
const outboundMessage = createOutboundMessage(connection, message)
await this.messageSender.sendMessage(outboundMessage)
await this.sendMessage(outboundMessage)

const event = await firstValueFrom(subject)
return event.payload.mediationRecord
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/transport/WsOutboundTransport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type WebSocket from 'ws'
import { AgentConfig } from '../agent/AgentConfig'
import { EventEmitter } from '../agent/EventEmitter'
import { AriesFrameworkError } from '../error/AriesFrameworkError'
import { Buffer } from '../utils/buffer'

import { TransportEventTypes } from './TransportEventTypes'

Expand Down Expand Up @@ -134,8 +135,8 @@ export class WsOutboundTransport implements OutboundTransport {
reject(error)
}

socket.onclose = async () => {
this.logger.debug(`WebSocket closing to ${endpoint}`)
socket.onclose = async (event: WebSocket.CloseEvent) => {
this.logger.debug(`WebSocket closing to ${endpoint}`, { event })
socket.removeEventListener('message', this.handleMessageEvent)
this.transportTable.delete(socketId)

Expand Down
14 changes: 7 additions & 7 deletions packages/react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@
"events": "^3.3.0"
},
"devDependencies": {
"@types/react-native": "^0.64.10",
"@types/indy-sdk-react-native": "npm:@types/indy-sdk@^1.16.6",
"@types/react-native": "^0.64.10",
"indy-sdk-react-native": "^0.1.13",
"react": "17.0.1",
"react-native": "0.64.2",
"rimraf": "~3.0.2",
"typescript": "~4.3.0",
"indy-sdk-react-native": "^0.1.13",
"react-native-fs": "^2.18.0",
"react-native-get-random-values": "^1.7.0",
"react-native-fs": "^2.18.0"
"rimraf": "~3.0.2",
"typescript": "~4.3.0"
},
"peerDependencies": {
"indy-sdk-react-native": "^0.1.13",
"react-native-get-random-values": "^1.7.0",
"react-native-fs": "^2.18.0"
"react-native-fs": "^2.18.0",
"react-native-get-random-values": "^1.7.0"
}
}