WebSocketServer.swift 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. //////////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // WebSocketServer.swift
  4. // Starscream
  5. //
  6. // Created by Dalton Cherry on 4/5/19.
  7. // Copyright © 2019 Vluxe. All rights reserved.
  8. //
  9. // Licensed under the Apache License, Version 2.0 (the "License");
  10. // you may not use this file except in compliance with the License.
  11. // You may obtain a copy of the License at
  12. //
  13. // http://www.apache.org/licenses/LICENSE-2.0
  14. //
  15. // Unless required by applicable law or agreed to in writing, software
  16. // distributed under the License is distributed on an "AS IS" BASIS,
  17. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. // See the License for the specific language governing permissions and
  19. // limitations under the License.
  20. //
  21. //////////////////////////////////////////////////////////////////////////////////////////////////
  22. #if canImport(Network)
  23. import Foundation
  24. import Network
  25. /// WebSocketServer is a Network.framework implementation of a WebSocket server
  26. @available(watchOS, unavailable)
  27. @available(macOS 10.14, iOS 12.0, watchOS 5.0, tvOS 12.0, *)
  28. public class WebSocketServer: Server, ConnectionDelegate {
  29. public var onEvent: ((ServerEvent) -> Void)?
  30. private var connections = [String: ServerConnection]()
  31. private var listener: NWListener?
  32. private let queue = DispatchQueue(label: "com.vluxe.starscream.server.networkstream", attributes: [])
  33. public init() {
  34. }
  35. public func start(address: String, port: UInt16) -> Error? {
  36. //TODO: support TLS cert adding/binding
  37. let parameters = NWParameters(tls: nil, tcp: NWProtocolTCP.Options())
  38. let p = NWEndpoint.Port(rawValue: port)!
  39. parameters.requiredLocalEndpoint = NWEndpoint.hostPort(host: NWEndpoint.Host.name(address, nil), port: p)
  40. guard let listener = try? NWListener(using: parameters, on: p) else {
  41. return WSError(type: .serverError, message: "unable to start the listener at: \(address):\(port)", code: 0)
  42. }
  43. listener.newConnectionHandler = {[weak self] conn in
  44. let transport = TCPTransport(connection: conn)
  45. let c = ServerConnection(transport: transport)
  46. c.delegate = self
  47. self?.connections[c.uuid] = c
  48. }
  49. // listener.stateUpdateHandler = { state in
  50. // switch state {
  51. // case .ready:
  52. // print("ready to get sockets!")
  53. // case .setup:
  54. // print("setup to get sockets!")
  55. // case .cancelled:
  56. // print("server cancelled!")
  57. // case .waiting(let error):
  58. // print("waiting error: \(error)")
  59. // case .failed(let error):
  60. // print("server failed: \(error)")
  61. // @unknown default:
  62. // print("wat?")
  63. // }
  64. // }
  65. self.listener = listener
  66. listener.start(queue: queue)
  67. return nil
  68. }
  69. public func didReceive(event: ServerEvent) {
  70. onEvent?(event)
  71. switch event {
  72. case .disconnected(let conn, _, _):
  73. guard let conn = conn as? ServerConnection else {
  74. return
  75. }
  76. connections.removeValue(forKey: conn.uuid)
  77. default:
  78. break
  79. }
  80. }
  81. }
  82. @available(macOS 10.14, iOS 12.0, watchOS 5.0, tvOS 12.0, *)
  83. public class ServerConnection: Connection, HTTPServerDelegate, FramerEventClient, FrameCollectorDelegate, TransportEventClient {
  84. let transport: TCPTransport
  85. private let httpHandler = FoundationHTTPServerHandler()
  86. private let framer = WSFramer(isServer: true)
  87. private let frameHandler = FrameCollector()
  88. private var didUpgrade = false
  89. public var onEvent: ((ConnectionEvent) -> Void)?
  90. public weak var delegate: ConnectionDelegate?
  91. private let id: String
  92. var uuid: String {
  93. return id
  94. }
  95. init(transport: TCPTransport) {
  96. self.id = UUID().uuidString
  97. self.transport = transport
  98. transport.register(delegate: self)
  99. httpHandler.register(delegate: self)
  100. framer.register(delegate: self)
  101. frameHandler.delegate = self
  102. }
  103. public func write(data: Data, opcode: FrameOpCode) {
  104. let wsData = framer.createWriteFrame(opcode: opcode, payload: data, isCompressed: false)
  105. transport.write(data: wsData, completion: {_ in })
  106. }
  107. // MARK: - TransportEventClient
  108. public func connectionChanged(state: ConnectionState) {
  109. switch state {
  110. case .connected:
  111. break
  112. case .waiting:
  113. break
  114. case .failed(let error):
  115. print("server connection error: \(error ?? WSError(type: .protocolError, message: "default error, no extra data", code: 0))") //handleError(error)
  116. case .viability(_):
  117. break
  118. case .shouldReconnect(_):
  119. break
  120. case .receive(let data):
  121. if didUpgrade {
  122. framer.add(data: data)
  123. } else {
  124. httpHandler.parse(data: data)
  125. }
  126. case .cancelled:
  127. print("server connection cancelled!")
  128. //broadcast(event: .cancelled)
  129. case .peerClosed:
  130. delegate?.didReceive(event: .disconnected(self, "Connection closed by peer", UInt16(FrameOpCode.connectionClose.rawValue)))
  131. }
  132. }
  133. /// MARK: - HTTPServerDelegate
  134. public func didReceive(event: HTTPEvent) {
  135. switch event {
  136. case .success(let headers):
  137. didUpgrade = true
  138. let response = httpHandler.createResponse(headers: [:])
  139. transport.write(data: response, completion: {_ in })
  140. delegate?.didReceive(event: .connected(self, headers))
  141. onEvent?(.connected(headers))
  142. case .failure(let error):
  143. onEvent?(.error(error))
  144. }
  145. }
  146. /// MARK: - FrameCollectorDelegate
  147. public func frameProcessed(event: FrameEvent) {
  148. switch event {
  149. case .frame(let frame):
  150. frameHandler.add(frame: frame)
  151. case .error(let error):
  152. onEvent?(.error(error))
  153. }
  154. }
  155. public func didForm(event: FrameCollector.Event) {
  156. switch event {
  157. case .text(let string):
  158. delegate?.didReceive(event: .text(self, string))
  159. onEvent?(.text(string))
  160. case .binary(let data):
  161. delegate?.didReceive(event: .binary(self, data))
  162. onEvent?(.binary(data))
  163. case .pong(let data):
  164. delegate?.didReceive(event: .pong(self, data))
  165. onEvent?(.pong(data))
  166. case .ping(let data):
  167. delegate?.didReceive(event: .ping(self, data))
  168. onEvent?(.ping(data))
  169. case .closed(let reason, let code):
  170. delegate?.didReceive(event: .disconnected(self, reason, code))
  171. onEvent?(.disconnected(reason, code))
  172. case .error(let error):
  173. onEvent?(.error(error))
  174. }
  175. }
  176. public func decompress(data: Data, isFinal: Bool) -> Data? {
  177. return nil
  178. }
  179. }
  180. #endif