2

I have been trying to integrate SignalR in my SwiftUI project, Websocket is establishing connection with negotiation response connection and immediately disconnecting within 20seconds.

Here are the logs: 2022-06-13T05:17:28.192Z debug: HttpConnection init 2022-06-13T05:17:28.201Z debug: HubConnection init 2022-06-13T05:17:28.202Z info: Registering client side hub method: 'Receive' 2022-06-13T05:17:28.203Z info: Starting hub connection 2022-06-13T05:17:28.203Z info: Starting reconnectable connection 2022-06-13T05:17:28.203Z debug: Attempting to chage state from: 'disconnected' to: 'starting' 2022-06-13T05:17:28.206Z debug: Changing state to: 'starting' succeeded 2022-06-13T05:17:28.206Z debug: Starting or reconnecting 2022-06-13T05:17:28.206Z debug: HttpConnection init 2022-06-13T05:17:28.206Z debug: HttpConnection deinit 2022-06-13T05:17:28.206Z info: Starting connection 2022-06-13T05:17:28.206Z debug: Attempting to chage state from: 'initial' to: 'connecting' 2022-06-13T05:17:28.207Z debug: Changing state to: 'connecting' succeeded 2022-06-13T05:17:28.216Z debug: HubConnection deinit 2022-06-13 10:47:29.208760+0530 TestSignalR[61887:5482369] [boringssl] boringssl_metrics_log_metric_block_invoke(151) Failed to log metrics 2022-06-13T05:17:29.497Z debug: Negotiate completed with OK status code 2022-06-13T05:17:29.497Z debug: Negotiate response: {"negotiateVersion":1,"connectionId":"fQUDgraRIqK1xsszHtq2oA","connectionToken":"4MZCS4PeTkFxOhxrfSv05w","availableTransports":[{"transport":"WebSockets","transferFormats":["Text","Binary"]},{"transport":"ServerSentEvents","transferFormats":["Text"]},{"transport":"LongPolling","transferFormats":["Text","Binary"]}]} 2022-06-13T05:17:29.500Z debug: Negotiation response received 2022-06-13T05:17:29.502Z info: Selected WebSockets transport 2022-06-13T05:17:29.503Z info: Starting WebSocket transport 2022-06-13T05:17:29.504Z debug: HttpConnection deinit 2022-06-13 10:47:29.614492+0530 TestSignalR[61887:5482376] [boringssl] boringssl_metrics_log_metric_block_invoke(151) Failed to log metrics 2022-06-13T05:17:30.313Z info: WebSocket open 2022-06-13T05:17:45.383Z info: WebSocket close. Code: 1000, reason: 2022-06-13T05:17:45.383Z debug: Marking transport as closed.

As we can't conform swiftUI view for HubConnectionDelegate for callbacks. Am creating a class where it can be conformed to the protocol and start hub connection. below is the code.

class SignalRController: UIViewController {
var hubConnection: HubConnection?
private var testSignalConnectionDelegate: HubConnectionDelegate?
override func viewDidLoad() {
}

func startSignalR() {
    guard let url = URL(string: "my_url_for_socket") else {
        return
    }
    self.testSignalConnectionDelegate = TestSignalConnectionDelegate(controller: self)
    self.hubConnection = HubConnectionBuilder(url: url)
        .withLogging(minLogLevel: .debug)
        .withHubConnectionDelegate(delegate: self.testSignalConnectionDelegate!)
        .withAutoReconnect()
        .build()
    self.hubConnection?.on(method: "Receive") { (message: String, _ : String) in
        if !message.isEmpty {
        }
    }
    self.hubConnection?.start()
}
}

class TestSignalConnectionDelegate: HubConnectionDelegate {

weak var controller: UIViewController?

init(controller: SignalRController) {
    self.controller = controller
}

func connectionDidOpen(hubConnection: HubConnection) {
    print("connection succeeded")
}

func connectionDidFailToOpen(error: Error) {
    print("connection failed")
}

func connectionDidClose(error: Error?) {
    print("connection closed")
}

func connectionWillReconnect(error: Error) {
    print("connection reconnection")
}

func connectionDidReconnect() {
    print("connection reconnected")
}
}

and calling this method in swiftUIview in onAppear statement as below.

struct ContentView: View {
var body: some View {
Text("Hello, world!")
.padding()
.onAppear {
let testSignalR = SignalRController()
testSignalR.startSignalR()
}
}
}

When same process am following in UIKit its working as expected. Please let me know if am missing anything or any mistake from my end. Any swiftUI sample with signalR would also be helpfull.

waiting for the reply.

Regards, J.Chandrasekhar Reddy

1 Answers1

1

Well, I cannot say the provided usage of UIViewController is correct (or what's you want to use later), but for now observed disconnection is because you create controller on stack so it is destroyed (and free everything related) right on quit from context.

So just to fix this make it a member

struct ContentView: View {
  let testSignalR = SignalRController()   // << here !!

  var body: some View {
    Text("Hello, world!")
      .padding()
      .onAppear {
        testSignalR.startSignalR()
      }
  }
}

Note: consider UIViewControllerRepresentable to work with controller as real controller presented own view.

Asperi
  • 228,894
  • 20
  • 464
  • 690