Ohm-Management - Projektarbeit B-ME
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

webSocket.d.ts 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import { WebSocketSubject, WebSocketSubjectConfig } from './WebSocketSubject';
  2. /**
  3. * Wrapper around the w3c-compatible WebSocket object provided by the browser.
  4. *
  5. * <span class="informal">{@link Subject} that communicates with a server via WebSocket</span>
  6. *
  7. * `webSocket` is a factory function that produces a `WebSocketSubject`,
  8. * which can be used to make WebSocket connection with an arbitrary endpoint.
  9. * `webSocket` accepts as an argument either a string with url of WebSocket endpoint, or an
  10. * {@link WebSocketSubjectConfig} object for providing additional configuration, as
  11. * well as Observers for tracking lifecycle of WebSocket connection.
  12. *
  13. * When `WebSocketSubject` is subscribed, it attempts to make a socket connection,
  14. * unless there is one made already. This means that many subscribers will always listen
  15. * on the same socket, thus saving resources. If however, two instances are made of `WebSocketSubject`,
  16. * even if these two were provided with the same url, they will attempt to make separate
  17. * connections. When consumer of a `WebSocketSubject` unsubscribes, socket connection is closed,
  18. * only if there are no more subscribers still listening. If after some time a consumer starts
  19. * subscribing again, connection is reestablished.
  20. *
  21. * Once connection is made, whenever a new message comes from the server, `WebSocketSubject` will emit that
  22. * message as a value in the stream. By default, a message from the socket is parsed via `JSON.parse`. If you
  23. * want to customize how deserialization is handled (if at all), you can provide custom `resultSelector`
  24. * function in {@link WebSocketSubject}. When connection closes, stream will complete, provided it happened without
  25. * any errors. If at any point (starting, maintaining or closing a connection) there is an error,
  26. * stream will also error with whatever WebSocket API has thrown.
  27. *
  28. * By virtue of being a {@link Subject}, `WebSocketSubject` allows for receiving and sending messages from the server. In order
  29. * to communicate with a connected endpoint, use `next`, `error` and `complete` methods. `next` sends a value to the server, so bear in mind
  30. * that this value will not be serialized beforehand. Because of This, `JSON.stringify` will have to be called on a value by hand,
  31. * before calling `next` with a result. Note also that if at the moment of nexting value
  32. * there is no socket connection (for example no one is subscribing), those values will be buffered, and sent when connection
  33. * is finally established. `complete` method closes socket connection. `error` does the same,
  34. * as well as notifying the server that something went wrong via status code and string with details of what happened.
  35. * Since status code is required in WebSocket API, `WebSocketSubject` does not allow, like regular `Subject`,
  36. * arbitrary values being passed to the `error` method. It needs to be called with an object that has `code`
  37. * property with status code number and optional `reason` property with string describing details
  38. * of an error.
  39. *
  40. * Calling `next` does not affect subscribers of `WebSocketSubject` - they have no
  41. * information that something was sent to the server (unless of course the server
  42. * responds somehow to a message). On the other hand, since calling `complete` triggers
  43. * an attempt to close socket connection. If that connection is closed without any errors, stream will
  44. * complete, thus notifying all subscribers. And since calling `error` closes
  45. * socket connection as well, just with a different status code for the server, if closing itself proceeds
  46. * without errors, subscribed Observable will not error, as one might expect, but complete as usual. In both cases
  47. * (calling `complete` or `error`), if process of closing socket connection results in some errors, *then* stream
  48. * will error.
  49. *
  50. * **Multiplexing**
  51. *
  52. * `WebSocketSubject` has an additional operator, not found in other Subjects. It is called `multiplex` and it is
  53. * used to simulate opening several socket connections, while in reality maintaining only one.
  54. * For example, an application has both chat panel and real-time notifications about sport news. Since these are two distinct functions,
  55. * it would make sense to have two separate connections for each. Perhaps there could even be two separate services with WebSocket
  56. * endpoints, running on separate machines with only GUI combining them together. Having a socket connection
  57. * for each functionality could become too resource expensive. It is a common pattern to have single
  58. * WebSocket endpoint that acts as a gateway for the other services (in this case chat and sport news services).
  59. * Even though there is a single connection in a client app, having the ability to manipulate streams as if it
  60. * were two separate sockets is desirable. This eliminates manually registering and unregistering in a gateway for
  61. * given service and filter out messages of interest. This is exactly what `multiplex` method is for.
  62. *
  63. * Method accepts three parameters. First two are functions returning subscription and unsubscription messages
  64. * respectively. These are messages that will be sent to the server, whenever consumer of resulting Observable
  65. * subscribes and unsubscribes. Server can use them to verify that some kind of messages should start or stop
  66. * being forwarded to the client. In case of the above example application, after getting subscription message with proper identifier,
  67. * gateway server can decide that it should connect to real sport news service and start forwarding messages from it.
  68. * Note that both messages will be sent as returned by the functions, meaning they will have to be serialized manually, just
  69. * as messages pushed via `next`. Also bear in mind that these messages will be sent on *every* subscription and
  70. * unsubscription. This is potentially dangerous, because one consumer of an Observable may unsubscribe and the server
  71. * might stop sending messages, since it got unsubscription message. This needs to be handled
  72. * on the server or using {@link publish} on a Observable returned from 'multiplex'.
  73. *
  74. * Last argument to `multiplex` is a `messageFilter` function which filters out messages
  75. * sent by the server to only those that belong to simulated WebSocket stream. For example, server might mark these
  76. * messages with some kind of string identifier on a message object and `messageFilter` would return `true`
  77. * if there is such identifier on an object emitted by the socket.
  78. *
  79. * Return value of `multiplex` is an Observable with messages incoming from emulated socket connection. Note that this
  80. * is not a `WebSocketSubject`, so calling `next` or `multiplex` again will fail. For pushing values to the
  81. * server, use root `WebSocketSubject`.
  82. *
  83. * ### Examples
  84. * #### Listening for messages from the server
  85. * const subject = Rx.Observable.webSocket('ws://localhost:8081');
  86. *
  87. * subject.subscribe(
  88. * (msg) => console.log('message received: ' + msg), // Called whenever there is a message from the server.
  89. * (err) => console.log(err), // Called if at any point WebSocket API signals some kind of error.
  90. * () => console.log('complete') // Called when connection is closed (for whatever reason).
  91. * );
  92. *
  93. *
  94. * #### Pushing messages to the server
  95. * const subject = Rx.Observable.webSocket('ws://localhost:8081');
  96. *
  97. * subject.subscribe(); // Note that at least one consumer has to subscribe to
  98. * // the created subject - otherwise "nexted" values will be just
  99. * // buffered and not sent, since no connection was established!
  100. *
  101. * subject.next(JSON.stringify({message: 'some message'})); // This will send a message to the server
  102. * // once a connection is made.
  103. * // Remember to serialize sent value first!
  104. *
  105. * subject.complete(); // Closes the connection.
  106. *
  107. *
  108. * subject.error({code: 4000, reason: 'I think our app just broke!'}); // Also closes the connection,
  109. * // but let's the server know that
  110. * // this closing is caused by some error.
  111. *
  112. *
  113. * #### Multiplexing WebSocket
  114. * const subject = Rx.Observable.webSocket('ws://localhost:8081');
  115. *
  116. * const observableA = subject.multiplex(
  117. * () => JSON.stringify({subscribe: 'A'}), // When server gets this message, it will start sending messages for 'A'...
  118. * () => JSON.stringify({unsubscribe: 'A'}), // ...and when gets this one, it will stop.
  119. * message => message.type === 'A' // Server will tag all messages for 'A' with type property.
  120. * );
  121. *
  122. * const observableB = subject.multiplex( // And the same goes for 'B'.
  123. * () => JSON.stringify({subscribe: 'B'}),
  124. * () => JSON.stringify({unsubscribe: 'B'}),
  125. * message => message.type === 'B'
  126. * );
  127. *
  128. * const subA = observableA.subscribe(messageForA => console.log(messageForA));
  129. * // At this moment WebSocket connection
  130. * // is established. Server gets '{"subscribe": "A"}'
  131. * // message and starts sending messages for 'A',
  132. * // which we log here.
  133. *
  134. * const subB = observableB.subscribe(messageForB => console.log(messageForB));
  135. * // Since we already have a connection,
  136. * // we just send '{"subscribe": "B"}' message
  137. * // to the server. It starts sending
  138. * // messages for 'B', which we log here.
  139. *
  140. * subB.unsubscribe();
  141. * // Message '{"unsubscribe": "B"}' is sent to the
  142. * // server, which stops sending 'B' messages.
  143. *
  144. * subA.unubscribe();
  145. * // Message '{"unsubscribe": "A"}' makes the server
  146. * // stop sending messages for 'A'. Since there is
  147. * // no more subscribers to root Subject, socket
  148. * // connection closes.
  149. *
  150. *
  151. *
  152. * @param {string|WebSocketSubjectConfig} urlConfigOrSource The WebSocket endpoint as an url or an object with
  153. * configuration and additional Observers.
  154. * @return {WebSocketSubject} Subject which allows to both send and receive messages via WebSocket connection.
  155. */
  156. export declare function webSocket<T>(urlConfigOrSource: string | WebSocketSubjectConfig<T>): WebSocketSubject<T>;