SwiftR icon indicating copy to clipboard operation
SwiftR copied to clipboard

My connection is established, but I can't invoke functions

Open CaptainHunter opened this issue 7 years ago • 9 comments

My connection is established, but I can't invoke functions. Surprisingly, the function on my hub did not even trigger (found out by logging every method call on my hub).

I have already tried invoking through a web browser and it's working fine, so I doubt the problem's from my SignalR hub. Would you kindly assist me again?

I am currently using signalR v2.2.1 and SwiftR 0.13.0

How I initialise my connection: let connection = SignalR(serverDomain + "/signalR") connection.useWKWebView = true connection.signalRVersion = .v2_2_1

How I setup my hub: screen shot 2017-04-30 at 12 03 39 pm

I've also tried invoking with the handle response, but it does not seem to be working or returning any feedback: try(hub.invoke("testConnection", arguments: nil) { (result, error) in print('FEEDBACK! :D') })

CaptainHunter avatar Apr 30 '17 04:04 CaptainHunter

Good Day

I currently have the same issue has it ever been solved?

Error: Object Reference not set to an instance of an object

Regards

hendricks28 avatar Jun 07 '17 13:06 hendricks28

Could you share more code? Is it structured similar to the SwiftR demo app? I'm wondering if you have the hub declared such that it's no longer in scope by the time the connect callback is executed.

adamhartford avatar Jun 07 '17 17:06 adamhartford

Hi thanks for your reply

I have structured it almost 100% like the demo except its all in a class that is created globally as signalR is used throughout the whole application so its done like this so that it runs once when the application has finished loading other values.

What works is I can receive the events for on and signal r stays connected throughout the app i can recieve its posts but the second I Invoke I either get "Error: Object Reference not set to an instance of an object" and then have to click the button 2 or 3 times before the invoke actually goes through.

Do you know anything that could cause this. The signalR implimentation was setup by my companies previous developers with no documentation so I am unsure of what the issue could be. Like I said if I spam the send button it works now and again

Sorry for late reply our time-zones must be different

Regards Lloyd Hendricks `` class ChatService{

var simpleHub: Hub! var complexHub: Hub!

var hubConnection: SignalR!

init() {

let guestID = _UserKeys.getGuestID()
let currentToken = _UserKeys.getToken()

let user = "g_\(guestID)"
let password = "\(currentToken)"
let credentialData = "\(user):\(password)".data(using: String.Encoding.utf8)!
let base64Credentials = credentialData.base64EncodedString(options: [])
let _headers = ["Authorization": "Basic \(base64Credentials)"]

// Hubs...
hubConnection = SignalR(_GlobalAPI.GET_SIGNALR_URL)
hubConnection.useWKWebView = true
hubConnection.transport = .auto
hubConnection.headers = _headers
hubConnection.signalRVersion = .v2_2_0
simpleHub = Hub("ChatHub")
simpleHub.isProxy()

simpleHub.on("addChatMessage") { args in

 let m: AnyObject = args![0] as AnyObject!
  
 let isFromGuest = m["isFromGuest"] as! Bool
  
  if(isFromGuest == false){
    
  // create a sound ID, in this case its the tweet sound.
  let systemSoundID: SystemSoundID = 1012
  
  // to play sound
  AudioServicesPlaySystemSound (systemSoundID)
    
  }
  
  NotificationCenter.default.post(name: MESSAGENOTIFICATION, object: nil)

}

hubConnection.addHub(simpleHub)

// SignalR events
hubConnection.starting = { [weak self] in
  print("Starting...")
  
  
}

hubConnection.reconnecting = { [weak self] in
  print("Reconnecting...")
 
}

hubConnection.connected = { [weak self] in
  print("Connected. Connection ID: \(String(describing: self!.hubConnection.connectionID))")
 
}

hubConnection.reconnected = { [weak self] in
  print("Reconnected. Connection ID: \(String(describing: self!.hubConnection.connectionID))")
  
}

hubConnection.disconnected = { [weak self] in
  print("Disconnected.")
  
}

hubConnection.connectionSlow = {
  print("Connection slow...")

}

hubConnection.error = { [weak self] error in
  print("Error: \(String(describing: error))")

  // Here's an example of how to automatically reconnect after a timeout.
  //
  // For example, on the device, if the app is in the background long enough
  // for the SignalR connection to time out, you'll get disconnected/error
  // notifications when the app becomes active again.
  
  if let source = error?["source"] as? String , source == "TimeoutException" {
    print("Connection timed out. Restarting...")
    self?.hubConnection.start()
  }
  
}

// hubConnection.start()

}

func StartSignalRConnection(){

hubConnection.start()

}

func StopSignalRConnection(){

hubConnection.stop()

}

func SendMessage(HotelID: CLong!, Message:String!){

if let hub = self.simpleHub, let message = Message {
    do {
      
      try hub.invoke("SendChatMessage", arguments: ["h_\(String(HotelID).description)", message])
      
    } catch {
      
      print(error)
      
    }
  
}

} }

hendricks28 avatar Jun 08 '17 07:06 hendricks28

Actually, Object reference not set to an instance of an object sounds like .NET runtime error, not Swift. If your transport is auto, and becomes WebSockets, remember that SwiftR doesn't support custom headers with WebSockets. It sounds possible that you're getting errors on the server side where headers are expected and not found.

adamhartford avatar Jun 08 '17 10:06 adamhartford

Hi

Thanks for the reply i will contact my API developer and ask him to confirm what the transport type is. What do you recommend using ?

Regards

hendricks28 avatar Jun 08 '17 10:06 hendricks28

Hi.

I'm using your library for an iOS app. I have almost the same issue, but I made SignalR to use WebSockets with headers, but just the first time I established the connection with SignalR and I could use invoke to get info from the server without errors. In headers, I send an access token for my server.

After that, I restarted the app and it tried to establish a new connection. Then SignalR tried first ServerSentEvents, which didn't work with authorization.

Next, it tried LongPolling. The authorization was successful but every time I use Invoke I get the same error message: "Object reference not set to an instance of an object."

As you say that SwiftR doesn't support custom headers with WebSockets, how could it work the first time?

And after using WebSockets the first time, why is not using it the next time when I restart the app?

Could we say that LongPolling doesn't work on iOS?

Thank you in advance!

Maireno avatar Jul 14 '17 12:07 Maireno

Any solution so far? My connection to Hub is established and I have connectionId as well. But I'm unable to call any server method and get following error everytime. message = "There was an error invoking Hub method 'chathub.updateCustomer'."

zahid119 avatar Aug 18 '17 14:08 zahid119

@zahid119 did you find any solution for that. ?

munsifhayat avatar Feb 28 '18 12:02 munsifhayat

Yes. I accidentally set all my hub functions private. I updated them to public and it worked perfectly. The connection was always getting established because Connect and Disconnection functions were overridden from parent class.

zahid119 avatar May 11 '18 06:05 zahid119