ue-softphone-sdk 2.2.3 → 2.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/bye.d.ts +16 -0
- package/dist/api/dtmf.d.ts +15 -0
- package/dist/api/emitter.d.ts +88 -0
- package/dist/api/exceptions/content-type-unsupported.d.ts +8 -0
- package/dist/api/exceptions/index.d.ts +5 -0
- package/dist/api/exceptions/request-pending.d.ts +9 -0
- package/dist/api/exceptions/session-description-handler.d.ts +8 -0
- package/dist/api/exceptions/session-terminated.d.ts +8 -0
- package/dist/api/exceptions/state-transition.d.ts +8 -0
- package/dist/api/index.d.ts +58 -0
- package/dist/api/info.d.ts +16 -0
- package/dist/api/invitation-accept-options.d.ts +19 -0
- package/dist/api/invitation-progress-options.d.ts +38 -0
- package/dist/api/invitation-reject-options.d.ts +25 -0
- package/dist/api/invitation.d.ts +179 -0
- package/dist/api/inviter-cancel-options.d.ts +9 -0
- package/dist/api/inviter-invite-options.d.ts +28 -0
- package/dist/api/inviter-options.d.ts +43 -0
- package/dist/api/inviter.d.ts +236 -0
- package/dist/api/message.d.ts +16 -0
- package/dist/api/messager-message-options.d.ts +11 -0
- package/dist/api/messager-options.d.ts +17 -0
- package/dist/api/messager.d.ts +26 -0
- package/dist/api/notification.d.ts +16 -0
- package/dist/api/notifier.d.ts +8 -0
- package/dist/api/publisher-options.d.ts +33 -0
- package/dist/api/publisher-publish-options.d.ts +6 -0
- package/dist/api/publisher-state.d.ts +21 -0
- package/dist/api/publisher-unpublish-options.d.ts +6 -0
- package/dist/api/publisher.d.ts +65 -0
- package/dist/api/referral.d.ts +38 -0
- package/dist/api/registerer-options.d.ts +46 -0
- package/dist/api/registerer-register-options.d.ts +11 -0
- package/dist/api/registerer-state.d.ts +21 -0
- package/dist/api/registerer-unregister-options.d.ts +16 -0
- package/dist/api/registerer.d.ts +144 -0
- package/dist/api/session-bye-options.d.ts +11 -0
- package/dist/api/session-delegate.d.ts +73 -0
- package/dist/api/session-description-handler-factory.d.ts +15 -0
- package/dist/api/session-description-handler.d.ts +74 -0
- package/dist/api/session-info-options.d.ts +11 -0
- package/dist/api/session-invite-options.d.ts +28 -0
- package/dist/api/session-message-options.d.ts +11 -0
- package/dist/api/session-options.d.ts +8 -0
- package/dist/api/session-refer-options.d.ts +14 -0
- package/dist/api/session-state.d.ts +45 -0
- package/dist/api/session.d.ts +359 -0
- package/dist/api/subscriber-options.d.ts +11 -0
- package/dist/api/subscriber-subscribe-options.d.ts +6 -0
- package/dist/api/subscriber.d.ts +94 -0
- package/dist/api/subscription-delegate.d.ts +12 -0
- package/dist/api/subscription-options.d.ts +8 -0
- package/dist/api/subscription-state.d.ts +19 -0
- package/dist/api/subscription-subscribe-options.d.ts +6 -0
- package/dist/api/subscription-unsubscribe-options.d.ts +6 -0
- package/dist/api/subscription.d.ts +84 -0
- package/dist/api/transport-state.d.ts +37 -0
- package/dist/api/transport.d.ts +159 -0
- package/dist/api/user-agent-delegate.d.ts +84 -0
- package/dist/api/user-agent-options.d.ts +253 -0
- package/dist/api/user-agent-state.d.ts +14 -0
- package/dist/api/user-agent.d.ts +200 -0
- package/dist/core/dialogs/dialog-state.d.ts +34 -0
- package/dist/core/dialogs/dialog.d.ts +161 -0
- package/dist/core/dialogs/index.d.ts +4 -0
- package/dist/core/dialogs/session-dialog.d.ts +196 -0
- package/dist/core/dialogs/subscription-dialog.d.ts +120 -0
- package/dist/core/exceptions/exception.d.ts +8 -0
- package/dist/core/exceptions/index.d.ts +3 -0
- package/dist/core/exceptions/transaction-state-error.d.ts +8 -0
- package/dist/core/exceptions/transport-error.d.ts +8 -0
- package/dist/core/index.d.ts +15 -0
- package/dist/core/log/index.d.ts +3 -0
- package/dist/core/log/levels.d.ts +10 -0
- package/dist/core/log/logger-factory.d.ts +21 -0
- package/dist/core/log/logger.d.ts +19 -0
- package/dist/core/messages/body.d.ts +64 -0
- package/dist/core/messages/digest-authentication.d.ts +51 -0
- package/dist/core/messages/incoming-message.d.ts +79 -0
- package/dist/core/messages/incoming-request-message.d.ts +10 -0
- package/dist/core/messages/incoming-request.d.ts +67 -0
- package/dist/core/messages/incoming-response-message.d.ts +10 -0
- package/dist/core/messages/incoming-response.d.ts +12 -0
- package/dist/core/messages/index.d.ts +13 -0
- package/dist/core/messages/md5.d.ts +32 -0
- package/dist/core/messages/methods/ack.d.ts +18 -0
- package/dist/core/messages/methods/bye.d.ts +21 -0
- package/dist/core/messages/methods/cancel.d.ts +21 -0
- package/dist/core/messages/methods/constants.d.ts +20 -0
- package/dist/core/messages/methods/index.d.ts +13 -0
- package/dist/core/messages/methods/info.d.ts +21 -0
- package/dist/core/messages/methods/invite.d.ts +86 -0
- package/dist/core/messages/methods/message.d.ts +21 -0
- package/dist/core/messages/methods/notify.d.ts +21 -0
- package/dist/core/messages/methods/prack.d.ts +21 -0
- package/dist/core/messages/methods/publish.d.ts +21 -0
- package/dist/core/messages/methods/refer.d.ts +21 -0
- package/dist/core/messages/methods/register.d.ts +21 -0
- package/dist/core/messages/methods/subscribe.d.ts +54 -0
- package/dist/core/messages/outgoing-request-message.d.ts +94 -0
- package/dist/core/messages/outgoing-request.d.ts +67 -0
- package/dist/core/messages/outgoing-response.d.ts +42 -0
- package/dist/core/messages/parser.d.ts +14 -0
- package/dist/core/messages/utils.d.ts +24 -0
- package/dist/core/session/index.d.ts +2 -0
- package/dist/core/session/session-delegate.d.ts +70 -0
- package/dist/core/session/session.d.ts +134 -0
- package/dist/core/subscription/index.d.ts +2 -0
- package/dist/core/subscription/subscription-delegate.d.ts +27 -0
- package/dist/core/subscription/subscription.d.ts +55 -0
- package/dist/core/timers.d.ts +20 -0
- package/dist/core/transactions/client-transaction.d.ts +45 -0
- package/dist/core/transactions/index.d.ts +10 -0
- package/dist/core/transactions/invite-client-transaction.d.ts +116 -0
- package/dist/core/transactions/invite-server-transaction.d.ts +127 -0
- package/dist/core/transactions/non-invite-client-transaction.d.ts +69 -0
- package/dist/core/transactions/non-invite-server-transaction.d.ts +57 -0
- package/dist/core/transactions/server-transaction.d.ts +35 -0
- package/dist/core/transactions/transaction-state.d.ts +13 -0
- package/dist/core/transactions/transaction-user.d.ts +72 -0
- package/dist/core/transactions/transaction.d.ts +79 -0
- package/dist/core/transport.d.ts +31 -0
- package/dist/core/user-agent-core/allowed-methods.d.ts +4 -0
- package/dist/core/user-agent-core/index.d.ts +3 -0
- package/dist/core/user-agent-core/user-agent-core-configuration.d.ts +99 -0
- package/dist/core/user-agent-core/user-agent-core-delegate.d.ts +37 -0
- package/dist/core/user-agent-core/user-agent-core.d.ts +179 -0
- package/dist/core/user-agents/bye-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/bye-user-agent-server.d.ts +10 -0
- package/dist/core/user-agents/cancel-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/index.d.ts +26 -0
- package/dist/core/user-agents/info-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/info-user-agent-server.d.ts +10 -0
- package/dist/core/user-agents/invite-user-agent-client.d.ts +35 -0
- package/dist/core/user-agents/invite-user-agent-server.d.ts +77 -0
- package/dist/core/user-agents/message-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/message-user-agent-server.d.ts +10 -0
- package/dist/core/user-agents/notify-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/notify-user-agent-server.d.ts +16 -0
- package/dist/core/user-agents/prack-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/prack-user-agent-server.d.ts +16 -0
- package/dist/core/user-agents/publish-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/re-invite-user-agent-client.d.ts +18 -0
- package/dist/core/user-agents/re-invite-user-agent-server.d.ts +41 -0
- package/dist/core/user-agents/re-subscribe-user-agent-client.d.ts +17 -0
- package/dist/core/user-agents/re-subscribe-user-agent-server.d.ts +10 -0
- package/dist/core/user-agents/refer-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/refer-user-agent-server.d.ts +16 -0
- package/dist/core/user-agents/register-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/register-user-agent-server.d.ts +11 -0
- package/dist/core/user-agents/subscribe-user-agent-client.d.ts +65 -0
- package/dist/core/user-agents/subscribe-user-agent-server.d.ts +11 -0
- package/dist/core/user-agents/user-agent-client.d.ts +103 -0
- package/dist/core/user-agents/user-agent-server.d.ts +79 -0
- package/dist/grammar/grammar.d.ts +26 -0
- package/dist/grammar/index.d.ts +4 -0
- package/dist/grammar/name-addr-header.d.ts +24 -0
- package/dist/grammar/parameters.d.ts +16 -0
- package/dist/grammar/pegjs/dist/grammar.d.ts +50 -0
- package/dist/grammar/uri.d.ts +62 -0
- package/dist/{types/index.d.ts → index.d.ts} +7 -3
- package/dist/main.d.ts +9 -0
- package/dist/new-index.d.ts +199 -0
- package/dist/platform/web/index.d.ts +4 -0
- package/dist/platform/web/modifiers/index.d.ts +5 -0
- package/dist/platform/web/modifiers/modifiers.d.ts +41 -0
- package/dist/platform/web/session-description-handler/index.d.ts +14 -0
- package/dist/platform/web/session-description-handler/media-stream-factory-default.d.ts +6 -0
- package/dist/platform/web/session-description-handler/media-stream-factory.d.ts +6 -0
- package/dist/platform/web/session-description-handler/peer-connection-configuration-default.d.ts +5 -0
- package/dist/platform/web/session-description-handler/peer-connection-delegate.d.ts +63 -0
- package/dist/platform/web/session-description-handler/session-description-handler-configuration.d.ts +16 -0
- package/dist/platform/web/session-description-handler/session-description-handler-factory-default.d.ts +11 -0
- package/dist/platform/web/session-description-handler/session-description-handler-factory-options.d.ts +9 -0
- package/dist/platform/web/session-description-handler/session-description-handler-factory.d.ts +16 -0
- package/dist/platform/web/session-description-handler/session-description-handler-options.d.ts +47 -0
- package/dist/platform/web/session-description-handler/session-description-handler.d.ts +212 -0
- package/dist/platform/web/simple-user/index.d.ts +7 -0
- package/dist/platform/web/simple-user/simple-user-delegate.d.ts +72 -0
- package/dist/platform/web/simple-user/simple-user-options.d.ts +90 -0
- package/dist/platform/web/simple-user/simple-user.d.ts +226 -0
- package/dist/platform/web/transport/index.d.ts +6 -0
- package/dist/platform/web/transport/transport-options.d.ts +30 -0
- package/dist/platform/web/transport/transport.d.ts +125 -0
- package/dist/ue-softphone-sdk.js +2 -1
- package/dist/ue-softphone-sdk.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/webPhoneSdk.d.ts +24 -0
- package/dist/webrtc.d.ts +17 -0
- package/{rollup-new.config.mjs → new-rollup.config.mjs} +1 -1
- package/package.json +6 -6
- package/rollup.config.js +15 -14
- package/src/api/api-extractor.json +358 -0
- package/src/api/bye.ts +27 -0
- package/src/api/dtmf.ts +27 -0
- package/src/api/emitter.ts +110 -0
- package/src/api/exceptions/content-type-unsupported.ts +11 -0
- package/src/api/exceptions/index.ts +5 -0
- package/src/api/exceptions/request-pending.ts +12 -0
- package/src/api/exceptions/session-description-handler.ts +11 -0
- package/src/api/exceptions/session-terminated.ts +11 -0
- package/src/api/exceptions/state-transition.ts +11 -0
- package/src/api/index.ts +58 -0
- package/src/api/info.ts +27 -0
- package/src/api/invitation-accept-options.ts +20 -0
- package/src/api/invitation-progress-options.ts +36 -0
- package/src/api/invitation-reject-options.ts +22 -0
- package/src/api/invitation.ts +816 -0
- package/src/api/inviter-cancel-options.ts +9 -0
- package/src/api/inviter-invite-options.ts +29 -0
- package/src/api/inviter-options.ts +44 -0
- package/src/api/inviter.ts +1126 -0
- package/src/api/message.ts +27 -0
- package/src/api/messager-message-options.ts +12 -0
- package/src/api/messager-options.ts +18 -0
- package/src/api/messager.ts +89 -0
- package/src/api/notification.ts +27 -0
- package/src/api/notifier.ts +7 -0
- package/src/api/publisher-options.ts +34 -0
- package/src/api/publisher-publish-options.ts +6 -0
- package/src/api/publisher-state.ts +21 -0
- package/src/api/publisher-unpublish-options.ts +6 -0
- package/src/api/publisher.ts +418 -0
- package/src/api/referral.ts +89 -0
- package/src/api/registerer-options.ts +55 -0
- package/src/api/registerer-register-options.ts +12 -0
- package/src/api/registerer-state.ts +21 -0
- package/src/api/registerer-unregister-options.ts +17 -0
- package/src/api/registerer.ts +814 -0
- package/src/api/session-bye-options.ts +12 -0
- package/src/api/session-delegate.ts +80 -0
- package/src/api/session-description-handler-factory.ts +16 -0
- package/src/api/session-description-handler.ts +89 -0
- package/src/api/session-info-options.ts +12 -0
- package/src/api/session-invite-options.ts +29 -0
- package/src/api/session-message-options.ts +12 -0
- package/src/api/session-options.ts +8 -0
- package/src/api/session-refer-options.ts +15 -0
- package/src/api/session-state.ts +45 -0
- package/src/api/session.ts +1448 -0
- package/src/api/subscriber-options.ts +12 -0
- package/src/api/subscriber-subscribe-options.ts +6 -0
- package/src/api/subscriber.ts +536 -0
- package/src/api/subscription-delegate.ts +13 -0
- package/src/api/subscription-options.ts +8 -0
- package/src/api/subscription-state.ts +19 -0
- package/src/api/subscription-subscribe-options.ts +6 -0
- package/src/api/subscription-unsubscribe-options.ts +6 -0
- package/src/api/subscription.ts +161 -0
- package/src/api/transport-state.ts +37 -0
- package/src/api/transport.ts +169 -0
- package/src/api/user-agent-delegate.ts +95 -0
- package/src/api/user-agent-options.ts +322 -0
- package/src/api/user-agent-state.ts +14 -0
- package/src/api/user-agent.ts +1014 -0
- package/src/core/api-extractor.json +358 -0
- package/src/core/dialogs/dialog-state.ts +35 -0
- package/src/core/dialogs/dialog.ts +605 -0
- package/src/core/dialogs/index.ts +4 -0
- package/src/core/dialogs/session-dialog.ts +996 -0
- package/src/core/dialogs/subscription-dialog.ts +557 -0
- package/src/core/exceptions/exception.ts +11 -0
- package/src/core/exceptions/index.ts +3 -0
- package/src/core/exceptions/transaction-state-error.ts +11 -0
- package/src/core/exceptions/transport-error.ts +11 -0
- package/src/core/index.ts +19 -0
- package/src/core/log/index.ts +3 -0
- package/src/core/log/levels.ts +10 -0
- package/src/core/log/logger-factory.ts +119 -0
- package/src/core/log/logger.ts +42 -0
- package/src/core/messages/body.ts +171 -0
- package/src/core/messages/digest-authentication.ts +190 -0
- package/src/core/messages/incoming-message.ts +152 -0
- package/src/core/messages/incoming-request-message.ts +14 -0
- package/src/core/messages/incoming-request.ts +75 -0
- package/src/core/messages/incoming-response-message.ts +14 -0
- package/src/core/messages/incoming-response.ts +13 -0
- package/src/core/messages/index.ts +18 -0
- package/src/core/messages/md5.ts +437 -0
- package/src/core/messages/methods/ack.ts +22 -0
- package/src/core/messages/methods/bye.ts +22 -0
- package/src/core/messages/methods/cancel.ts +22 -0
- package/src/core/messages/methods/constants.ts +21 -0
- package/src/core/messages/methods/index.ts +13 -0
- package/src/core/messages/methods/info.ts +22 -0
- package/src/core/messages/methods/invite.ts +104 -0
- package/src/core/messages/methods/message.ts +22 -0
- package/src/core/messages/methods/notify.ts +22 -0
- package/src/core/messages/methods/prack.ts +22 -0
- package/src/core/messages/methods/publish.ts +22 -0
- package/src/core/messages/methods/refer.ts +22 -0
- package/src/core/messages/methods/register.ts +22 -0
- package/src/core/messages/methods/subscribe.ts +59 -0
- package/src/core/messages/outgoing-request-message.ts +299 -0
- package/src/core/messages/outgoing-request.ts +77 -0
- package/src/core/messages/outgoing-response.ts +174 -0
- package/src/core/messages/parser.ts +265 -0
- package/src/core/messages/utils.ts +144 -0
- package/src/core/session/index.ts +2 -0
- package/src/core/session/session-delegate.ts +88 -0
- package/src/core/session/session.ts +158 -0
- package/src/core/subscription/index.ts +2 -0
- package/src/core/subscription/subscription-delegate.ts +30 -0
- package/src/core/subscription/subscription.ts +61 -0
- package/src/core/timers.ts +24 -0
- package/src/core/transactions/client-transaction.ts +78 -0
- package/src/core/transactions/index.ts +10 -0
- package/src/core/transactions/invite-client-transaction.ts +504 -0
- package/src/core/transactions/invite-server-transaction.ts +432 -0
- package/src/core/transactions/non-invite-client-transaction.ts +257 -0
- package/src/core/transactions/non-invite-server-transaction.ts +241 -0
- package/src/core/transactions/server-transaction.ts +47 -0
- package/src/core/transactions/transaction-state.ts +13 -0
- package/src/core/transactions/transaction-user.ts +82 -0
- package/src/core/transactions/transaction.ts +149 -0
- package/src/core/transport.ts +32 -0
- package/src/core/user-agent-core/allowed-methods.ts +19 -0
- package/src/core/user-agent-core/index.ts +3 -0
- package/src/core/user-agent-core/user-agent-core-configuration.ts +111 -0
- package/src/core/user-agent-core/user-agent-core-delegate.ts +50 -0
- package/src/core/user-agent-core/user-agent-core.ts +905 -0
- package/src/core/user-agents/bye-user-agent-client.ts +16 -0
- package/src/core/user-agents/bye-user-agent-server.ts +14 -0
- package/src/core/user-agents/cancel-user-agent-client.ts +14 -0
- package/src/core/user-agents/index.ts +26 -0
- package/src/core/user-agents/info-user-agent-client.ts +15 -0
- package/src/core/user-agents/info-user-agent-server.ts +14 -0
- package/src/core/user-agents/invite-user-agent-client.ts +405 -0
- package/src/core/user-agents/invite-user-agent-server.ts +269 -0
- package/src/core/user-agents/message-user-agent-client.ts +14 -0
- package/src/core/user-agents/message-user-agent-server.ts +14 -0
- package/src/core/user-agents/notify-user-agent-client.ts +15 -0
- package/src/core/user-agents/notify-user-agent-server.ts +30 -0
- package/src/core/user-agents/prack-user-agent-client.ts +16 -0
- package/src/core/user-agents/prack-user-agent-server.ts +37 -0
- package/src/core/user-agents/publish-user-agent-client.ts +14 -0
- package/src/core/user-agents/re-invite-user-agent-client.ts +127 -0
- package/src/core/user-agents/re-invite-user-agent-server.ts +109 -0
- package/src/core/user-agents/re-subscribe-user-agent-client.ts +78 -0
- package/src/core/user-agents/re-subscribe-user-agent-server.ts +14 -0
- package/src/core/user-agents/refer-user-agent-client.ts +15 -0
- package/src/core/user-agents/refer-user-agent-server.ts +30 -0
- package/src/core/user-agents/register-user-agent-client.ts +14 -0
- package/src/core/user-agents/register-user-agent-server.ts +14 -0
- package/src/core/user-agents/subscribe-user-agent-client.ts +341 -0
- package/src/core/user-agents/subscribe-user-agent-server.ts +14 -0
- package/src/core/user-agents/user-agent-client.ts +378 -0
- package/src/core/user-agents/user-agent-server.ts +276 -0
- package/src/grammar/grammar.ts +55 -0
- package/src/grammar/index.ts +4 -0
- package/src/grammar/name-addr-header.ts +58 -0
- package/src/grammar/parameters.ts +45 -0
- package/src/grammar/pegjs/README.md +9 -0
- package/src/grammar/pegjs/dist/grammar.ts +1557 -0
- package/src/grammar/pegjs/src/grammar.pegjs +1009 -0
- package/src/grammar/uri.ts +370 -0
- package/src/index.ts +49 -26
- package/src/lib/socket.io.esm.min.js +7 -0
- package/src/main.ts +26 -0
- package/src/new-index.ts +2486 -0
- package/src/platform/react/README.md +1 -0
- package/src/platform/web/index.ts +4 -0
- package/src/platform/web/modifiers/index.ts +5 -0
- package/src/platform/web/modifiers/modifiers.ts +180 -0
- package/src/platform/web/session-description-handler/api-extractor.json +358 -0
- package/src/platform/web/session-description-handler/index.ts +14 -0
- package/src/platform/web/session-description-handler/media-stream-factory-default.ts +22 -0
- package/src/platform/web/session-description-handler/media-stream-factory.ts +10 -0
- package/src/platform/web/session-description-handler/peer-connection-configuration-default.ts +17 -0
- package/src/platform/web/session-description-handler/peer-connection-delegate.ts +72 -0
- package/src/platform/web/session-description-handler/session-description-handler-configuration.ts +17 -0
- package/src/platform/web/session-description-handler/session-description-handler-factory-default.ts +45 -0
- package/src/platform/web/session-description-handler/session-description-handler-factory-options.ts +10 -0
- package/src/platform/web/session-description-handler/session-description-handler-factory.ts +17 -0
- package/src/platform/web/session-description-handler/session-description-handler-options.ts +56 -0
- package/src/platform/web/session-description-handler/session-description-handler.ts +938 -0
- package/src/platform/web/simple-user/api-extractor.json +358 -0
- package/src/platform/web/simple-user/index.ts +7 -0
- package/src/platform/web/simple-user/simple-user-delegate.ts +82 -0
- package/src/platform/web/simple-user/simple-user-options.ts +102 -0
- package/src/platform/web/simple-user/simple-user.ts +1099 -0
- package/src/platform/web/transport/api-extractor.json +358 -0
- package/src/platform/web/transport/index.ts +6 -0
- package/src/platform/web/transport/transport-options.ts +34 -0
- package/src/platform/web/transport/transport.ts +742 -0
- package/src/version.ts +8 -0
- package/src/webPhoneSdk.ts +67 -0
- package/src/webrtc.ts +318 -0
- package/tsconfig.json +26 -10
- /package/dist/{types/config.d.ts → config.d.ts} +0 -0
|
@@ -0,0 +1,742 @@
|
|
|
1
|
+
import { Emitter, EmitterImpl } from "../../../api/emitter";
|
|
2
|
+
import { StateTransitionError } from "../../../api/exceptions";
|
|
3
|
+
import { Transport as TransportDefinition } from "../../../api/transport";
|
|
4
|
+
import { TransportState } from "../../../api/transport-state";
|
|
5
|
+
import { Grammar, Logger } from "../../../core";
|
|
6
|
+
import { TransportOptions } from "./transport-options";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Transport for SIP over secure WebSocket (WSS).
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export class Transport implements TransportDefinition {
|
|
13
|
+
private static defaultOptions: Required<TransportOptions> = {
|
|
14
|
+
server: "",
|
|
15
|
+
connectionTimeout: 5,
|
|
16
|
+
keepAliveInterval: 0,
|
|
17
|
+
keepAliveDebounce: 10,
|
|
18
|
+
traceSip: true
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
public onConnect: (() => void) | undefined;
|
|
22
|
+
public onDisconnect: ((error?: Error) => void) | undefined;
|
|
23
|
+
public onMessage: ((message: string) => void) | undefined;
|
|
24
|
+
|
|
25
|
+
private _protocol: string;
|
|
26
|
+
private _state: TransportState = TransportState.Disconnected;
|
|
27
|
+
private _stateEventEmitter: EmitterImpl<TransportState>;
|
|
28
|
+
private _ws: WebSocket | undefined;
|
|
29
|
+
|
|
30
|
+
private configuration: Required<TransportOptions>;
|
|
31
|
+
|
|
32
|
+
private connectPromise: Promise<void> | undefined;
|
|
33
|
+
private connectResolve: (() => void) | undefined;
|
|
34
|
+
private connectReject: ((error: Error) => void) | undefined;
|
|
35
|
+
private connectTimeout: number | undefined;
|
|
36
|
+
|
|
37
|
+
private disconnectPromise: Promise<void> | undefined;
|
|
38
|
+
private disconnectResolve: (() => void) | undefined;
|
|
39
|
+
private disconnectReject: ((error?: Error) => void) | undefined;
|
|
40
|
+
|
|
41
|
+
private keepAliveInterval: number | undefined;
|
|
42
|
+
private keepAliveDebounceTimeout: number | undefined;
|
|
43
|
+
|
|
44
|
+
private logger: Logger;
|
|
45
|
+
private transitioningState = false;
|
|
46
|
+
|
|
47
|
+
constructor(logger: Logger, options?: TransportOptions) {
|
|
48
|
+
// state emitter
|
|
49
|
+
this._stateEventEmitter = new EmitterImpl<TransportState>();
|
|
50
|
+
|
|
51
|
+
// logger
|
|
52
|
+
this.logger = logger;
|
|
53
|
+
|
|
54
|
+
// guard deprecated options (remove this in version 16.x)
|
|
55
|
+
if (options) {
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
57
|
+
const optionsDeprecated: any = options;
|
|
58
|
+
const wsServersDeprecated: string | Array<string> | undefined = optionsDeprecated?.wsServers;
|
|
59
|
+
const maxReconnectionAttemptsDeprecated: number | undefined = optionsDeprecated?.maxReconnectionAttempts;
|
|
60
|
+
if (wsServersDeprecated !== undefined) {
|
|
61
|
+
const deprecatedMessage =
|
|
62
|
+
`The transport option "wsServers" as has apparently been specified and has been deprecated. ` +
|
|
63
|
+
"It will no longer be available starting with SIP.js release 0.16.0. Please update accordingly.";
|
|
64
|
+
this.logger.warn(deprecatedMessage);
|
|
65
|
+
}
|
|
66
|
+
if (maxReconnectionAttemptsDeprecated !== undefined) {
|
|
67
|
+
const deprecatedMessage =
|
|
68
|
+
`The transport option "maxReconnectionAttempts" as has apparently been specified and has been deprecated. ` +
|
|
69
|
+
"It will no longer be available starting with SIP.js release 0.16.0. Please update accordingly.";
|
|
70
|
+
this.logger.warn(deprecatedMessage);
|
|
71
|
+
}
|
|
72
|
+
// hack
|
|
73
|
+
if (wsServersDeprecated && !options.server) {
|
|
74
|
+
if (typeof wsServersDeprecated === "string") {
|
|
75
|
+
options.server = wsServersDeprecated;
|
|
76
|
+
}
|
|
77
|
+
if (wsServersDeprecated instanceof Array) {
|
|
78
|
+
options.server = wsServersDeprecated[0];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// initialize configuration
|
|
84
|
+
this.configuration = {
|
|
85
|
+
// start with the default option values
|
|
86
|
+
...Transport.defaultOptions,
|
|
87
|
+
// apply any options passed in via the constructor
|
|
88
|
+
...options
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// validate server URL
|
|
92
|
+
const url = this.configuration.server;
|
|
93
|
+
const parsed: { scheme: string } | -1 = Grammar.parse(url, "absoluteURI");
|
|
94
|
+
if (parsed === -1) {
|
|
95
|
+
this.logger.error(`Invalid WebSocket Server URL "${url}"`);
|
|
96
|
+
throw new Error("Invalid WebSocket Server URL");
|
|
97
|
+
}
|
|
98
|
+
if (!["wss", "ws", "udp"].includes(parsed.scheme)) {
|
|
99
|
+
this.logger.error(`Invalid scheme in WebSocket Server URL "${url}"`);
|
|
100
|
+
throw new Error("Invalid scheme in WebSocket Server URL");
|
|
101
|
+
}
|
|
102
|
+
this._protocol = parsed.scheme.toUpperCase();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
public dispose(): Promise<void> {
|
|
106
|
+
return this.disconnect();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* The protocol.
|
|
111
|
+
*
|
|
112
|
+
* @remarks
|
|
113
|
+
* Formatted as defined for the Via header sent-protocol transport.
|
|
114
|
+
* https://tools.ietf.org/html/rfc3261#section-20.42
|
|
115
|
+
*/
|
|
116
|
+
public get protocol(): string {
|
|
117
|
+
return this._protocol;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* The URL of the WebSocket Server.
|
|
122
|
+
*/
|
|
123
|
+
public get server(): string {
|
|
124
|
+
return this.configuration.server;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Transport state.
|
|
129
|
+
*/
|
|
130
|
+
public get state(): TransportState {
|
|
131
|
+
return this._state;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Transport state change emitter.
|
|
136
|
+
*/
|
|
137
|
+
public get stateChange(): Emitter<TransportState> {
|
|
138
|
+
return this._stateEventEmitter;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* The WebSocket.
|
|
143
|
+
*/
|
|
144
|
+
public get ws(): WebSocket | undefined {
|
|
145
|
+
return this._ws;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Connect to network.
|
|
150
|
+
* Resolves once connected. Otherwise rejects with an Error.
|
|
151
|
+
*/
|
|
152
|
+
public connect(): Promise<void> {
|
|
153
|
+
return this._connect();
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Disconnect from network.
|
|
158
|
+
* Resolves once disconnected. Otherwise rejects with an Error.
|
|
159
|
+
*/
|
|
160
|
+
public disconnect(): Promise<void> {
|
|
161
|
+
return this._disconnect();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Returns true if the `state` equals "Connected".
|
|
166
|
+
* @remarks
|
|
167
|
+
* This is equivalent to `state === TransportState.Connected`.
|
|
168
|
+
*/
|
|
169
|
+
public isConnected(): boolean {
|
|
170
|
+
return this.state === TransportState.Connected;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Sends a message.
|
|
175
|
+
* Resolves once message is sent. Otherwise rejects with an Error.
|
|
176
|
+
* @param message - Message to send.
|
|
177
|
+
*/
|
|
178
|
+
public send(message: string): Promise<void> {
|
|
179
|
+
// Error handling is independent of whether the message was a request or
|
|
180
|
+
// response.
|
|
181
|
+
//
|
|
182
|
+
// If the transport user asks for a message to be sent over an
|
|
183
|
+
// unreliable transport, and the result is an ICMP error, the behavior
|
|
184
|
+
// depends on the type of ICMP error. Host, network, port or protocol
|
|
185
|
+
// unreachable errors, or parameter problem errors SHOULD cause the
|
|
186
|
+
// transport layer to inform the transport user of a failure in sending.
|
|
187
|
+
// Source quench and TTL exceeded ICMP errors SHOULD be ignored.
|
|
188
|
+
//
|
|
189
|
+
// If the transport user asks for a request to be sent over a reliable
|
|
190
|
+
// transport, and the result is a connection failure, the transport
|
|
191
|
+
// layer SHOULD inform the transport user of a failure in sending.
|
|
192
|
+
// https://tools.ietf.org/html/rfc3261#section-18.4
|
|
193
|
+
return this._send(message);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
private _connect(): Promise<void> {
|
|
197
|
+
this.logger.log(`Connecting ${this.server}`);
|
|
198
|
+
|
|
199
|
+
switch (this.state) {
|
|
200
|
+
case TransportState.Connecting:
|
|
201
|
+
// If `state` is "Connecting", `state` MUST NOT transition before returning.
|
|
202
|
+
if (this.transitioningState) {
|
|
203
|
+
return Promise.reject(this.transitionLoopDetectedError(TransportState.Connecting));
|
|
204
|
+
}
|
|
205
|
+
if (!this.connectPromise) {
|
|
206
|
+
throw new Error("Connect promise must be defined.");
|
|
207
|
+
}
|
|
208
|
+
return this.connectPromise; // Already connecting
|
|
209
|
+
case TransportState.Connected:
|
|
210
|
+
// If `state` is "Connected", `state` MUST NOT transition before returning.
|
|
211
|
+
if (this.transitioningState) {
|
|
212
|
+
return Promise.reject(this.transitionLoopDetectedError(TransportState.Connecting));
|
|
213
|
+
}
|
|
214
|
+
if (this.connectPromise) {
|
|
215
|
+
throw new Error("Connect promise must not be defined.");
|
|
216
|
+
}
|
|
217
|
+
return Promise.resolve(); // Already connected
|
|
218
|
+
case TransportState.Disconnecting:
|
|
219
|
+
// If `state` is "Disconnecting", `state` MUST transition to "Connecting" before returning
|
|
220
|
+
if (this.connectPromise) {
|
|
221
|
+
throw new Error("Connect promise must not be defined.");
|
|
222
|
+
}
|
|
223
|
+
try {
|
|
224
|
+
this.transitionState(TransportState.Connecting);
|
|
225
|
+
} catch (e) {
|
|
226
|
+
if (e instanceof StateTransitionError) {
|
|
227
|
+
return Promise.reject(e); // Loop detected
|
|
228
|
+
}
|
|
229
|
+
throw e;
|
|
230
|
+
}
|
|
231
|
+
break;
|
|
232
|
+
case TransportState.Disconnected:
|
|
233
|
+
// If `state` is "Disconnected" `state` MUST transition to "Connecting" before returning
|
|
234
|
+
if (this.connectPromise) {
|
|
235
|
+
throw new Error("Connect promise must not be defined.");
|
|
236
|
+
}
|
|
237
|
+
try {
|
|
238
|
+
this.transitionState(TransportState.Connecting);
|
|
239
|
+
} catch (e) {
|
|
240
|
+
if (e instanceof StateTransitionError) {
|
|
241
|
+
return Promise.reject(e); // Loop detected
|
|
242
|
+
}
|
|
243
|
+
throw e;
|
|
244
|
+
}
|
|
245
|
+
break;
|
|
246
|
+
default:
|
|
247
|
+
throw new Error("Unknown state");
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
let ws: WebSocket;
|
|
251
|
+
try {
|
|
252
|
+
// WebSocket()
|
|
253
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/WebSocket
|
|
254
|
+
ws = new WebSocket(this.server, "sip");
|
|
255
|
+
ws.binaryType = "arraybuffer"; // set data type of received binary messages
|
|
256
|
+
ws.addEventListener("close", (ev: CloseEvent) => this.onWebSocketClose(ev, ws));
|
|
257
|
+
ws.addEventListener("error", (ev: Event) => this.onWebSocketError(ev, ws));
|
|
258
|
+
ws.addEventListener("open", (ev: Event) => this.onWebSocketOpen(ev, ws));
|
|
259
|
+
ws.addEventListener("message", (ev: MessageEvent) => this.onWebSocketMessage(ev, ws));
|
|
260
|
+
this._ws = ws;
|
|
261
|
+
} catch (error) {
|
|
262
|
+
this._ws = undefined;
|
|
263
|
+
this.logger.error("WebSocket construction failed.");
|
|
264
|
+
this.logger.error(error);
|
|
265
|
+
return new Promise((resolve, reject) => {
|
|
266
|
+
this.connectResolve = resolve;
|
|
267
|
+
this.connectReject = reject;
|
|
268
|
+
// The `state` MUST transition to "Disconnecting" or "Disconnected" before rejecting
|
|
269
|
+
this.transitionState(TransportState.Disconnected, error);
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
this.connectPromise = new Promise((resolve, reject) => {
|
|
274
|
+
this.connectResolve = resolve;
|
|
275
|
+
this.connectReject = reject;
|
|
276
|
+
|
|
277
|
+
this.connectTimeout = window.setTimeout(() => {
|
|
278
|
+
this.logger.warn(
|
|
279
|
+
"Connect timed out. " +
|
|
280
|
+
"Exceeded time set in configuration.connectionTimeout: " +
|
|
281
|
+
this.configuration.connectionTimeout +
|
|
282
|
+
"s."
|
|
283
|
+
);
|
|
284
|
+
ws.close(1000); // careful here to use a local reference instead of this._ws
|
|
285
|
+
}, this.configuration.connectionTimeout * 1000);
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
return this.connectPromise;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
private _disconnect(): Promise<void> {
|
|
292
|
+
this.logger.log(`Disconnecting ${this.server}`);
|
|
293
|
+
|
|
294
|
+
switch (this.state) {
|
|
295
|
+
case TransportState.Connecting:
|
|
296
|
+
// If `state` is "Connecting", `state` MUST transition to "Disconnecting" before returning.
|
|
297
|
+
if (this.disconnectPromise) {
|
|
298
|
+
throw new Error("Disconnect promise must not be defined.");
|
|
299
|
+
}
|
|
300
|
+
try {
|
|
301
|
+
this.transitionState(TransportState.Disconnecting);
|
|
302
|
+
} catch (e) {
|
|
303
|
+
if (e instanceof StateTransitionError) {
|
|
304
|
+
return Promise.reject(e); // Loop detected
|
|
305
|
+
}
|
|
306
|
+
throw e;
|
|
307
|
+
}
|
|
308
|
+
break;
|
|
309
|
+
case TransportState.Connected:
|
|
310
|
+
// If `state` is "Connected", `state` MUST transition to "Disconnecting" before returning.
|
|
311
|
+
if (this.disconnectPromise) {
|
|
312
|
+
throw new Error("Disconnect promise must not be defined.");
|
|
313
|
+
}
|
|
314
|
+
try {
|
|
315
|
+
this.transitionState(TransportState.Disconnecting);
|
|
316
|
+
} catch (e) {
|
|
317
|
+
if (e instanceof StateTransitionError) {
|
|
318
|
+
return Promise.reject(e); // Loop detected
|
|
319
|
+
}
|
|
320
|
+
throw e;
|
|
321
|
+
}
|
|
322
|
+
break;
|
|
323
|
+
case TransportState.Disconnecting:
|
|
324
|
+
// If `state` is "Disconnecting", `state` MUST NOT transition before returning.
|
|
325
|
+
if (this.transitioningState) {
|
|
326
|
+
return Promise.reject(this.transitionLoopDetectedError(TransportState.Disconnecting));
|
|
327
|
+
}
|
|
328
|
+
if (!this.disconnectPromise) {
|
|
329
|
+
throw new Error("Disconnect promise must be defined.");
|
|
330
|
+
}
|
|
331
|
+
return this.disconnectPromise; // Already disconnecting
|
|
332
|
+
case TransportState.Disconnected:
|
|
333
|
+
// If `state` is "Disconnected", `state` MUST NOT transition before returning.
|
|
334
|
+
if (this.transitioningState) {
|
|
335
|
+
return Promise.reject(this.transitionLoopDetectedError(TransportState.Disconnecting));
|
|
336
|
+
}
|
|
337
|
+
if (this.disconnectPromise) {
|
|
338
|
+
throw new Error("Disconnect promise must not be defined.");
|
|
339
|
+
}
|
|
340
|
+
return Promise.resolve(); // Already disconnected
|
|
341
|
+
default:
|
|
342
|
+
throw new Error("Unknown state");
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (!this._ws) {
|
|
346
|
+
throw new Error("WebSocket must be defined.");
|
|
347
|
+
}
|
|
348
|
+
const ws = this._ws;
|
|
349
|
+
|
|
350
|
+
this.disconnectPromise = new Promise((resolve, reject) => {
|
|
351
|
+
this.disconnectResolve = resolve;
|
|
352
|
+
this.disconnectReject = reject;
|
|
353
|
+
|
|
354
|
+
try {
|
|
355
|
+
// WebSocket.close()
|
|
356
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close
|
|
357
|
+
ws.close(1000); // careful here to use a local reference instead of this._ws
|
|
358
|
+
} catch (error) {
|
|
359
|
+
// Treating this as a coding error as it apparently can only happen
|
|
360
|
+
// if you pass close() invalid parameters (so it should never happen)
|
|
361
|
+
this.logger.error("WebSocket close failed.");
|
|
362
|
+
this.logger.error(error);
|
|
363
|
+
throw error;
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
return this.disconnectPromise;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
private _send(message: string): Promise<void> {
|
|
371
|
+
if (this.configuration.traceSip === true) {
|
|
372
|
+
this.logger.log("Sending WebSocket message:\n\n" + message + "\n");
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (this._state !== TransportState.Connected) {
|
|
376
|
+
return Promise.reject(new Error("Not connected."));
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (!this._ws) {
|
|
380
|
+
throw new Error("WebSocket undefined.");
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
try {
|
|
384
|
+
// WebSocket.send()
|
|
385
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send
|
|
386
|
+
this._ws.send(message);
|
|
387
|
+
} catch (error) {
|
|
388
|
+
if (error instanceof Error) {
|
|
389
|
+
return Promise.reject(error);
|
|
390
|
+
}
|
|
391
|
+
return Promise.reject(new Error("WebSocket send failed."));
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return Promise.resolve();
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* WebSocket "onclose" event handler.
|
|
399
|
+
* @param ev - Event.
|
|
400
|
+
*/
|
|
401
|
+
private onWebSocketClose(ev: CloseEvent, ws: WebSocket): void {
|
|
402
|
+
if (ws !== this._ws) {
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const message = `WebSocket closed ${this.server} (code: ${ev.code})`;
|
|
407
|
+
const error = !this.disconnectPromise ? new Error(message) : undefined;
|
|
408
|
+
if (error) {
|
|
409
|
+
this.logger.warn("WebSocket closed unexpectedly");
|
|
410
|
+
}
|
|
411
|
+
this.logger.log(message);
|
|
412
|
+
|
|
413
|
+
// We are about to transition to disconnected, so clear our web socket
|
|
414
|
+
this._ws = undefined;
|
|
415
|
+
|
|
416
|
+
// The `state` MUST transition to "Disconnected" before resolving (assuming `state` is not already "Disconnected").
|
|
417
|
+
this.transitionState(TransportState.Disconnected, error);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* WebSocket "onerror" event handler.
|
|
422
|
+
* @param ev - Event.
|
|
423
|
+
*/
|
|
424
|
+
private onWebSocketError(ev: Event, ws: WebSocket): void {
|
|
425
|
+
if (ws !== this._ws) {
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
this.logger.error("WebSocket error occurred.");
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* WebSocket "onmessage" event handler.
|
|
433
|
+
* @param ev - Event.
|
|
434
|
+
*/
|
|
435
|
+
private onWebSocketMessage(ev: MessageEvent, ws: WebSocket): void {
|
|
436
|
+
if (ws !== this._ws) {
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
const data = ev.data;
|
|
441
|
+
let finishedData: string;
|
|
442
|
+
|
|
443
|
+
// CRLF Keep Alive response from server. Clear our keep alive timeout.
|
|
444
|
+
if (/^(\r\n)+$/.test(data)) {
|
|
445
|
+
this.clearKeepAliveTimeout();
|
|
446
|
+
if (this.configuration.traceSip === true) {
|
|
447
|
+
this.logger.log("Received WebSocket message with CRLF Keep Alive response");
|
|
448
|
+
}
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
if (!data) {
|
|
453
|
+
this.logger.warn("Received empty message, discarding...");
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
if (typeof data !== "string") {
|
|
458
|
+
// WebSocket binary message.
|
|
459
|
+
try {
|
|
460
|
+
finishedData = new TextDecoder().decode(new Uint8Array(data));
|
|
461
|
+
// TextDecoder (above) is not supported by old browsers, but it correctly decodes UTF-8.
|
|
462
|
+
// The line below is an ISO 8859-1 (Latin 1) decoder, so just UTF-8 code points that are 1 byte.
|
|
463
|
+
// It's old code and works in old browsers (IE), so leaving it here in a comment in case someone needs it.
|
|
464
|
+
// finishedData = String.fromCharCode.apply(null, (new Uint8Array(data) as unknown as Array<number>));
|
|
465
|
+
} catch (err) {
|
|
466
|
+
this.logger.error(err);
|
|
467
|
+
this.logger.error("Received WebSocket binary message failed to be converted into string, message discarded");
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
if (this.configuration.traceSip === true) {
|
|
471
|
+
this.logger.log("Received WebSocket binary message:\n\n" + finishedData + "\n");
|
|
472
|
+
}
|
|
473
|
+
} else {
|
|
474
|
+
// WebSocket text message.
|
|
475
|
+
finishedData = data;
|
|
476
|
+
if (this.configuration.traceSip === true) {
|
|
477
|
+
this.logger.log("Received WebSocket text message:\n\n" + finishedData + "\n");
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
if (this.state !== TransportState.Connected) {
|
|
482
|
+
this.logger.warn("Received message while not connected, discarding...");
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
if (this.onMessage) {
|
|
487
|
+
try {
|
|
488
|
+
this.onMessage(finishedData);
|
|
489
|
+
} catch (e) {
|
|
490
|
+
this.logger.error(e);
|
|
491
|
+
this.logger.error("Exception thrown by onMessage callback");
|
|
492
|
+
throw e; // rethrow unhandled exception
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* WebSocket "onopen" event handler.
|
|
499
|
+
* @param ev - Event.
|
|
500
|
+
*/
|
|
501
|
+
private onWebSocketOpen(ev: Event, ws: WebSocket): void {
|
|
502
|
+
if (ws !== this._ws) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
if (this._state === TransportState.Connecting) {
|
|
506
|
+
this.logger.log(`WebSocket opened ${this.server}`);
|
|
507
|
+
this.transitionState(TransportState.Connected);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Helper function to generate an Error.
|
|
513
|
+
* @param state - State transitioning to.
|
|
514
|
+
*/
|
|
515
|
+
private transitionLoopDetectedError(state: string): StateTransitionError {
|
|
516
|
+
let message = `A state transition loop has been detected.`;
|
|
517
|
+
message += ` An attempt to transition from ${this._state} to ${state} before the prior transition completed.`;
|
|
518
|
+
message += ` Perhaps you are synchronously calling connect() or disconnect() from a callback or state change handler?`;
|
|
519
|
+
this.logger.error(message);
|
|
520
|
+
return new StateTransitionError("Loop detected.");
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Transition transport state.
|
|
525
|
+
* @internal
|
|
526
|
+
*/
|
|
527
|
+
private transitionState(newState: TransportState, error?: Error): void {
|
|
528
|
+
const invalidTransition = (): Error => {
|
|
529
|
+
throw new Error(`Invalid state transition from ${this._state} to ${newState}`);
|
|
530
|
+
};
|
|
531
|
+
|
|
532
|
+
if (this.transitioningState) {
|
|
533
|
+
throw this.transitionLoopDetectedError(newState);
|
|
534
|
+
}
|
|
535
|
+
this.transitioningState = true;
|
|
536
|
+
|
|
537
|
+
// Validate state transition
|
|
538
|
+
switch (this._state) {
|
|
539
|
+
case TransportState.Connecting:
|
|
540
|
+
if (
|
|
541
|
+
newState !== TransportState.Connected &&
|
|
542
|
+
newState !== TransportState.Disconnecting &&
|
|
543
|
+
newState !== TransportState.Disconnected
|
|
544
|
+
) {
|
|
545
|
+
invalidTransition();
|
|
546
|
+
}
|
|
547
|
+
break;
|
|
548
|
+
case TransportState.Connected:
|
|
549
|
+
if (newState !== TransportState.Disconnecting && newState !== TransportState.Disconnected) {
|
|
550
|
+
invalidTransition();
|
|
551
|
+
}
|
|
552
|
+
break;
|
|
553
|
+
case TransportState.Disconnecting:
|
|
554
|
+
if (newState !== TransportState.Connecting && newState !== TransportState.Disconnected) {
|
|
555
|
+
invalidTransition();
|
|
556
|
+
}
|
|
557
|
+
break;
|
|
558
|
+
case TransportState.Disconnected:
|
|
559
|
+
if (newState !== TransportState.Connecting) {
|
|
560
|
+
invalidTransition();
|
|
561
|
+
}
|
|
562
|
+
break;
|
|
563
|
+
default:
|
|
564
|
+
throw new Error("Unknown state.");
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
// Update state
|
|
568
|
+
const oldState = this._state;
|
|
569
|
+
this._state = newState;
|
|
570
|
+
|
|
571
|
+
// Local copies of connect promises (guarding against callbacks changing them indirectly)
|
|
572
|
+
// const connectPromise = this.connectPromise;
|
|
573
|
+
const connectResolve = this.connectResolve;
|
|
574
|
+
const connectReject = this.connectReject;
|
|
575
|
+
|
|
576
|
+
// Reset connect promises if no longer connecting
|
|
577
|
+
if (oldState === TransportState.Connecting) {
|
|
578
|
+
this.connectPromise = undefined;
|
|
579
|
+
this.connectResolve = undefined;
|
|
580
|
+
this.connectReject = undefined;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// Local copies of disconnect promises (guarding against callbacks changing them indirectly)
|
|
584
|
+
// const disconnectPromise = this.disconnectPromise;
|
|
585
|
+
const disconnectResolve = this.disconnectResolve;
|
|
586
|
+
const disconnectReject = this.disconnectReject;
|
|
587
|
+
|
|
588
|
+
// Reset disconnect promises if no longer disconnecting
|
|
589
|
+
if (oldState === TransportState.Disconnecting) {
|
|
590
|
+
this.disconnectPromise = undefined;
|
|
591
|
+
this.disconnectResolve = undefined;
|
|
592
|
+
this.disconnectReject = undefined;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
// Clear any outstanding connect timeout
|
|
596
|
+
if (this.connectTimeout) {
|
|
597
|
+
clearTimeout(this.connectTimeout);
|
|
598
|
+
this.connectTimeout = undefined;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
this.logger.log(`Transitioned from ${oldState} to ${this._state}`);
|
|
602
|
+
this._stateEventEmitter.emit(this._state);
|
|
603
|
+
|
|
604
|
+
// Transition to Connected
|
|
605
|
+
if (newState === TransportState.Connected) {
|
|
606
|
+
this.startSendingKeepAlives();
|
|
607
|
+
if (this.onConnect) {
|
|
608
|
+
try {
|
|
609
|
+
this.onConnect();
|
|
610
|
+
} catch (e) {
|
|
611
|
+
this.logger.error(e);
|
|
612
|
+
this.logger.error("Exception thrown by onConnect callback");
|
|
613
|
+
throw e; // rethrow unhandled exception
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// Transition from Connected
|
|
619
|
+
if (oldState === TransportState.Connected) {
|
|
620
|
+
this.stopSendingKeepAlives();
|
|
621
|
+
if (this.onDisconnect) {
|
|
622
|
+
try {
|
|
623
|
+
if (error) {
|
|
624
|
+
this.onDisconnect(error);
|
|
625
|
+
} else {
|
|
626
|
+
this.onDisconnect();
|
|
627
|
+
}
|
|
628
|
+
} catch (e) {
|
|
629
|
+
this.logger.error(e);
|
|
630
|
+
this.logger.error("Exception thrown by onDisconnect callback");
|
|
631
|
+
throw e; // rethrow unhandled exception
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
// Complete connect promise
|
|
637
|
+
if (oldState === TransportState.Connecting) {
|
|
638
|
+
if (!connectResolve) {
|
|
639
|
+
throw new Error("Connect resolve undefined.");
|
|
640
|
+
}
|
|
641
|
+
if (!connectReject) {
|
|
642
|
+
throw new Error("Connect reject undefined.");
|
|
643
|
+
}
|
|
644
|
+
newState === TransportState.Connected ? connectResolve() : connectReject(error || new Error("Connect aborted."));
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// Complete disconnect promise
|
|
648
|
+
if (oldState === TransportState.Disconnecting) {
|
|
649
|
+
if (!disconnectResolve) {
|
|
650
|
+
throw new Error("Disconnect resolve undefined.");
|
|
651
|
+
}
|
|
652
|
+
if (!disconnectReject) {
|
|
653
|
+
throw new Error("Disconnect reject undefined.");
|
|
654
|
+
}
|
|
655
|
+
newState === TransportState.Disconnected
|
|
656
|
+
? disconnectResolve()
|
|
657
|
+
: disconnectReject(error || new Error("Disconnect aborted."));
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
this.transitioningState = false;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// TODO: Review "KeepAlive Stuff".
|
|
664
|
+
// It is not clear if it works and there are no tests for it.
|
|
665
|
+
// It was blindly lifted the keep alive code unchanged from earlier transport code.
|
|
666
|
+
//
|
|
667
|
+
// From the RFC...
|
|
668
|
+
//
|
|
669
|
+
// SIP WebSocket Clients and Servers may keep their WebSocket
|
|
670
|
+
// connections open by sending periodic WebSocket "Ping" frames as
|
|
671
|
+
// described in [RFC6455], Section 5.5.2.
|
|
672
|
+
// ...
|
|
673
|
+
// The indication and use of the CRLF NAT keep-alive mechanism defined
|
|
674
|
+
// for SIP connection-oriented transports in [RFC5626], Section 3.5.1 or
|
|
675
|
+
// [RFC6223] are, of course, usable over the transport defined in this
|
|
676
|
+
// specification.
|
|
677
|
+
// https://tools.ietf.org/html/rfc7118#section-6
|
|
678
|
+
//
|
|
679
|
+
// and...
|
|
680
|
+
//
|
|
681
|
+
// The Ping frame contains an opcode of 0x9.
|
|
682
|
+
// https://tools.ietf.org/html/rfc6455#section-5.5.2
|
|
683
|
+
//
|
|
684
|
+
// ==============================
|
|
685
|
+
// KeepAlive Stuff
|
|
686
|
+
// ==============================
|
|
687
|
+
|
|
688
|
+
private clearKeepAliveTimeout(): void {
|
|
689
|
+
if (this.keepAliveDebounceTimeout) {
|
|
690
|
+
clearTimeout(this.keepAliveDebounceTimeout);
|
|
691
|
+
}
|
|
692
|
+
this.keepAliveDebounceTimeout = undefined;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* Send a keep-alive (a double-CRLF sequence).
|
|
697
|
+
*/
|
|
698
|
+
private sendKeepAlive(): Promise<void> {
|
|
699
|
+
if (this.keepAliveDebounceTimeout) {
|
|
700
|
+
// We already have an outstanding keep alive, do not send another.
|
|
701
|
+
return Promise.resolve();
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
this.keepAliveDebounceTimeout = window.setTimeout(() => {
|
|
705
|
+
this.clearKeepAliveTimeout();
|
|
706
|
+
}, this.configuration.keepAliveDebounce * 1000);
|
|
707
|
+
|
|
708
|
+
return this.send("\r\n\r\n");
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* Start sending keep-alives.
|
|
713
|
+
*/
|
|
714
|
+
private startSendingKeepAlives(): void {
|
|
715
|
+
// Compute an amount of time in seconds to wait before sending another keep-alive.
|
|
716
|
+
const computeKeepAliveTimeout = (upperBound: number): number => {
|
|
717
|
+
const lowerBound = upperBound * 0.8;
|
|
718
|
+
return 1000 * (Math.random() * (upperBound - lowerBound) + lowerBound);
|
|
719
|
+
};
|
|
720
|
+
|
|
721
|
+
if (this.configuration.keepAliveInterval && !this.keepAliveInterval) {
|
|
722
|
+
this.keepAliveInterval = window.setInterval(() => {
|
|
723
|
+
this.sendKeepAlive();
|
|
724
|
+
this.startSendingKeepAlives();
|
|
725
|
+
}, computeKeepAliveTimeout(this.configuration.keepAliveInterval));
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
* Stop sending keep-alives.
|
|
731
|
+
*/
|
|
732
|
+
private stopSendingKeepAlives(): void {
|
|
733
|
+
if (this.keepAliveInterval) {
|
|
734
|
+
clearInterval(this.keepAliveInterval);
|
|
735
|
+
}
|
|
736
|
+
if (this.keepAliveDebounceTimeout) {
|
|
737
|
+
clearTimeout(this.keepAliveDebounceTimeout);
|
|
738
|
+
}
|
|
739
|
+
this.keepAliveInterval = undefined;
|
|
740
|
+
this.keepAliveDebounceTimeout = undefined;
|
|
741
|
+
}
|
|
742
|
+
}
|