The ReceiveTransport delegate methods (`onConnect` and `onConnectionStateChange`…) are not being called at all. This issue does not occur with SendTransport, where delegate methods work fine.
Here is the implementation of **RoomClient** for reference:
```
final internal class RoomClient {
...
...
...
func createSendTransport() {
// Do nothing if send transport is already created
if (self.sendTransport != nil) {
print("createSendTransport() send transport is already created...")
return
}
self.createWebRtcTransport(direction: "send")
print("createSendTransport() send transport created")
}
func createRecvTransport() {
// Do nothing if recv transport is already created
if (self.recvTransport != nil) {
print("createRecvTransport() recv transport is already created...")
return
}
self.createWebRtcTransport(direction: "recv")
print("createRecvTransport() recv transport created")
}
...
...
...
private func createICEServers() -> String {
let iceServers: [[String: Any]] = [
[
"urls": ["turn server url here"],
"username": "user-1",
"credential": "pass-1"
]
// ,
// [
// "urls": ["stun:stun.l.google.com:19302"]
// ]
]
if let jsonData = try? JSONSerialization.data(withJSONObject: iceServers, options: []),
let jsonString = String(data: jsonData, encoding: .utf8) {
return jsonString
}
return "[]"
}
private func createWebRtcTransport(direction: String) {
let reqID = direction == "send" ? SEND_TRANSPORT_ID : RECEIVE_TRANSPORT_ID
let isProducing = direction == "send" ? true : false
let isConsuming = direction == "recv" ? true : false
// socket call
let response: JSON = Request.shared.sendCreateWebRtcTransportRequest(socket: self.socket, id: reqID, producing: isProducing, consuming: isConsuming)
print("createWebRtcTransport() response = " + response.description)
let webRtcTransportData: JSON = response["data"]
let id: String = webRtcTransportData["id"].stringValue
let iceParameters: JSON = webRtcTransportData["iceParameters"]
let iceCandidatesArray: JSON = webRtcTransportData["iceCandidates"]
let dtlsParameters: JSON = webRtcTransportData["dtlsParameters"]
let iceServers: String = self.createICEServers()
switch direction {
case "send":
print("createWebRtcTransport() iceServers = " + iceServers)
do {
self.sendTransport = try self.device.createSendTransport(
id: id,
iceParameters: iceParameters.description,
iceCandidates: iceCandidatesArray.description,
dtlsParameters: dtlsParameters.description,
sctpParameters: nil,
iceServers: iceServers,
iceTransportPolicy: .all,
appData: nil)
self.sendTransportHandler = SendTransportHandler.init(parent: self)
self.sendTransport!.delegate = self.sendTransportHandler!
} catch {
print("createWebRtcTransport() failed to create send transport " + error.localizedDescription)
}
case "recv":
do {
self.recvTransport = try self.device.createReceiveTransport(
id: id,
iceParameters: iceParameters.description,
iceCandidates: iceCandidatesArray.description,
dtlsParameters: dtlsParameters.description,
sctpParameters: nil,
iceServers: iceServers,
iceTransportPolicy: .all,
appData: nil)
self.recvTransportHandler = RecvTransportHandler.init(parent: self)
self.recvTransport!.delegate = self.recvTransportHandler!
guard let recvTransport = self.recvTransport else {
print("Receive Transport not created")
return
}
print("Receive Transport created with id: \(recvTransport.id)")
// Play consumers that have been stored
for consumerInfo in self.consumersInfo {
self.consumeTrack(consumerInfo: consumerInfo)
}
} catch {
print("createWebRtcTransport() failed to create recv transport " + error.localizedDescription)
}
default:
print("createWebRtcTransport() invalid direction " + direction)
}
}
private func handleLocalTransportConnectEvent(transport: Transport, dtlsParameters: String) {
print("handleLocalTransportConnectEvent() id =" + transport.id)
Request.shared.sendConnectWebRtcTransportRequest(socket: self.socket, transportId: transport.id, dtlsParameters: dtlsParameters)
}
private func handleLocalTransportProduceEvent(transport: Transport, kind: String, rtpParameters: String, appData: String) -> String {
print("handleLocalTransportProduceEvent() id =" + transport.id + " kind = " + kind)
let transportProduceResponse: JSON = Request.shared.sendProduceWebRtcTransportRequest(socket: self.socket, transportId: transport.id, kind: kind, rtpParameters: rtpParameters, appData: appData)
return transportProduceResponse["producerId"].stringValue
}
// Class to handle send transport listener events
private class SendTransportHandler: SendTransportDelegate {
private var parent: RoomClient
init(parent: RoomClient) {
self.parent = parent
}
func onConnect(transport: any Mediasoup.Transport, dtlsParameters: String) {
print("SendTransport::onConnect dtlsParameters = " + dtlsParameters)
self.parent.handleLocalTransportConnectEvent(transport: transport, dtlsParameters: dtlsParameters)
}
func onConnectionStateChange(transport: any Mediasoup.Transport, connectionState: Mediasoup.TransportConnectionState) {
print("SendTransport::onConnectionStateChange connectionState = \(connectionState)")
}
func onProduce(transport: any Mediasoup.Transport, kind: Mediasoup.MediaKind, rtpParameters: String, appData: String, callback: @escaping (String?) -> Void) {
print("SendTransport::onProduce kind = \(kind)")
let kindString = kind == .audio ? "audio" : "video"
let producerId = self.parent.handleLocalTransportProduceEvent(transport: transport, kind: kindString, rtpParameters: rtpParameters, appData: appData)
callback(producerId)
}
func onProduceData(transport: any Mediasoup.Transport, sctpParameters: String, label: String, protocol dataProtocol: String, appData: String, callback: @escaping (String?) -> Void) {
print("SendTransport::onProduceData")
}
}
// Class to handle recv transport listener events
private class RecvTransportHandler: ReceiveTransportDelegate {
private var parent: RoomClient
init(parent: RoomClient) {
self.parent = parent
}
func onConnect(transport: any Mediasoup.Transport, dtlsParameters: String) {
print("RecvTransport::onConnect")
self.parent.handleLocalTransportConnectEvent(transport: transport, dtlsParameters: dtlsParameters)
}
func onConnectionStateChange(transport: any Mediasoup.Transport, connectionState: Mediasoup.TransportConnectionState) {
print("RecvTransport::onConnectionStateChange newState = \(connectionState)")
}
}
// Class to handle producer listener events
private class ProducerHandler: ProducerDelegate {
func onTransportClose(in producer: Mediasoup.Producer) {
print("Producer::onTransportClose")
}
}
// Class to handle consumer listener events
private class ConsumerHandler: ConsumerDelegate {
func onTransportClose(in consumer: Mediasoup.Consumer) {
print("Consumer::onTransportClose")
}
}
}
```
**Additional Context**
- The SendTransport delegate methods work as expected.
- Ice servers are configured properly, and WebRTC parameters seem correct.