ethand91 / mediasoup-ios-client

Mediasoup 3 iOS Client
ISC License
131 stars 65 forks source link

self.socket.connect won't throw or connect #57

Closed xplatsolutions closed 4 years ago

xplatsolutions commented 4 years ago

Without touching the sample-media-server and just changing the config.js listenIps: [ { ip: '192.168.2.2', announcedIp: undefined } ], to my local IP address it seems that my client application refuses to show any sign of connection. I haven't touched the SSL certs from the sample-media-server repo.

I am using the below pods

pod "mediasoup_ios_client", "~> 1.5.0"
pod "Starscream", "~> 4.0.3"

Starscream made some minor changes so I had to change EchoSocket to the below initialization.

func connect(wsUri: String) throws {
    /*
     if !wsUri.starts(with: "ws://") || !wsUri.starts(with: "wss://") {
     throw SocketError.INVALID_WS_URI
     }
     */

    if (self.socket != nil && isConnected) {
      return
    }

    let request = URLRequest(url: URL(string: wsUri)!)

    // Allow self-signed certificates
    // Load certificates and public keys into an app bundle, use the builtin pinner and TrustKit.
    let pinner = FoundationSecurity(allowSelfSigned: true) // don't validate SSL certificates

    self.socket = WebSocket.init(request: request, certPinner: inner)
    // ^^^^^^ Initializing the socket changed to latest Starscream pod ^^^^^^

    // Handle socket delegate methods on the global thread (semaphor will lock if not set to global..)
    self.socket!.callbackQueue = DispatchQueue.global()
    self.socket!.delegate = self
    self.socket!.connect()
  }

Below is my code, trying to keep it short to make sure I understand the steps.

import Foundation
import Combine
import SwiftyJSON
import WebRTC

final internal class HostBroadcastViewModel: ObservableObject, Identifiable {

  public let roomId: String

  private let disposables = Set<AnyCancellable>()
  private let socket: IMediaSocket

  private var room: IRoomManager?
  private var roomDelegate: RoomListener?

  init(mediaSocket: IMediaSocket, roomId: String) {
    socket = mediaSocket
    self.roomId = roomId
  }

  func startBroadcasting() {
    self.socket.register(observer: self)
    print("Will connect to server")

    do {
      try self.socket.connect(wsUri: "wss://192.168.2.2:443") // Doesn't throw or any sign of connection
    } catch {
      print("Failed to connect to server")
    }

  }

  private func handleWebSocketConnected() {
    // Initialize mediasoup client
    initializeMediasoup()

    // Get router rtp capabilities
    let getRoomRtpCapabilitiesResponse: JSON = Request.shared.sendGetRoomRtpCapabilitiesRequest(socket: socket, roomId: roomId)
    print("response! " + getRoomRtpCapabilitiesResponse.description)
    let roomRtpCapabilities: JSON = getRoomRtpCapabilitiesResponse["roomRtpCapabilities"]
    print("roomRtpCapabilities " + roomRtpCapabilities.description)

    // Initialize mediasoup device
    let device: MediasoupDevice = MediasoupDevice.init()
    device.load(roomRtpCapabilities.description)

    print("handleWebSocketConnected() device loaded")

    room = AppDependencyContainer.shared.createMediasoupRoomManager(socket: socket, device: device, roomId: roomId)
    roomDelegate = self
    room!.roomListener = roomDelegate

    // Join the room
    do {
      try room!.join()
    } catch {
      print("failed to join room")
      return
    }

    // Create recv webrtcTransport
    room!.createRecvTransport()
    // Create send webrtcTransport
    room!.createSendTransport()

    // Start media capture/sending
//    self.displayLocalVideo()
  }

  private func initializeMediasoup() {
    Mediasoupclient.initialize()
    print("initializeMediasoup() client initialized")

    // Set mediasoup log
    Logger.setLogLevel(LogLevel.WARN)
    Logger.setDefaultHandler()
  }

}

extension HostBroadcastViewModel : MessageObserver {
  func on(event: String, data: JSON?) { 
    // Never invoked after connect() is called
    switch event {
      case ActionEvent.OPEN:
        print("socket connected")
        self.handleWebSocketConnected()
        break
      case ActionEvent.NEW_USER:
        print("NEW_USER id =" + data!["userId"]["userId"].stringValue)
        break
      case ActionEvent.NEW_CONSUMER:
        print("NEW_CONSUMER data=" + data!.description)
        self.handleNewConsumerEvent(consumerInfo: data!["consumerData"])
        break
      default:
        print("Unknown event " + event)
    }
  }

  private func handleNewConsumerEvent(consumerInfo: JSON) {
    print("handleNewConsumerEvent info = " + consumerInfo.description)
    // Start consuming
    room!.consumeTrack(consumerInfo: consumerInfo)
  }
}

// Extension for RoomListener
extension HostBroadcastViewModel : RoomListener {
  func onNewConsumer(consumer: Consumer) {
    print("RoomListener::onNewConsumer kind=" + consumer.getKind())

    if consumer.getKind() == "video" {
      let videoTrack: RTCVideoTrack = consumer.getTrack() as! RTCVideoTrack
      videoTrack.isEnabled = true
//      videoTrack.add(self.remoteVideoView) - I have to see how to bind this in SwiftUI
    }

    do {
      consumer.getKind() == "video"
        ? try room!.resumeRemoteVideo()
        : try room!.resumeRemoteAudio()
    } catch {
      print("onNewConsumer() failed to resume remote track")
    }
  }
}

Server starting successfully

initializeWorkers() [num:8]
websocket SSL server running on port 443

Config.js

const os = require('os');

module.exports = Object.freeze({
  numWorkers: Object.keys(os.cpus()).length,
  worker: {
    logLevel: 'debug',
    logTags: [
      'rtp',
      'rtcp',
      'ice',
      'dtls'
    ],
    rtcMinPort: 40000,
    rtcMaxPort: 49999
  },
  router: {
    mediaCodecs: [
      {
        kind: 'audio',
        mimeType: 'audio/opus',
        clockRate: 48000,
        channels: 2,
      },
      {
        kind: 'video',
        mimeType: 'video/VP8',
        clockRate: 90000,
      }
    ]
  },
  webRtcTransport: {
    listenIps: [ { ip: '192.168.2.2', announcedIp: undefined } ],
    enableUdp: true,
    enableTcp: true,
    preferUdp: true,
    preferTcp: false
  }
});

Any help how to debug is appreciated

xplatsolutions commented 4 years ago

I noticed that the WebSocket.Server log message WebSocket.Server started at port 8080 never actually printed in my console, sounds like I am missing some configuration;

ethand91 commented 4 years ago

Unrelated to mediasoup, is the wss url correct? Does the connection timeout after a while? Can you connect from another websocket?

xplatsolutions commented 4 years ago

Yes, I know :/ you can close if you want, was just looking for some help to debug this.

Shouldn't the was URL be my local IP; wss://192.168.2.2:443, I didn't change the scheme from what you had, only the IP address point to my local. What do you mean to connect from another WebSocket?

I think I will try with the sample server from mediasoup site using an Express layer.

ethand91 commented 4 years ago

The url should reference the ip of which the server is running.

What do you mean to connect from another WebSocket?

Create a simple HTML page that connects to your websocket server, and see if that works.

You could also use tools like tcpdump on the server to see if it's actually receiving any tcp packets on connect. Also check to make sure the 443 port on your server is actually listening.

xplatsolutions commented 4 years ago

Thanks will check it out. Actually the server is running localhost.