nuclearace / Socket.IO-Client-Swift

socket.io-client for Swift
Other
361 stars 53 forks source link

Cannot authenticate (receiving authorizationError) #81

Closed danipralea closed 9 years ago

danipralea commented 9 years ago

Hello! I am receiving unauthorized error when trying to connect/authenticate (see below):

My entire code is :

NSDictionary * parameters = [NSDictionary dictionaryWithObject:serverToken forKey:@"token"];
NSArray * parametersArray = [NSArray arrayWithObject:parameters];

self.socketIOClient = [[SocketIOClient alloc] initWithSocketURL:serverURL opts:@{@"log": @YES, @"reconnectAttempts" : @5, @"reconnects" : @YES, @"connectParams": parameters}];

[self.socketIOClient on:@"connect" callback:^(NSArray* data, SocketAckEmitter* ack) {
NSLog(@"socket connected");
    [self.socketIOClient on:@"authenticate" callback:^(NSArray * data, SocketAckEmitter * ack) {
        NSLog(@"authenticated");
        NSLog(@"data : %@", data);
        NSLog(@"ack : %@", ack);
    }];
    [self.socketIOClient emitWithAck:@"authenticate" withItems:parametersArray];
}];

[self.socketIOClient onAny:^(SocketAnyEvent * event) {
    NSLog(@"any event : %@", event);
}];

[self.socketIOClient connect];

and I receive :

Log SocketIOClient: Socket connected
Log SocketIOClient: Handling event: connect with data: (
)
any event : SocketAnyEvent: Event: connect items: Optional((
))
socket connected
Log SocketIOClient: Adding handler for event: authenticate
Log SocketEngine: Got polling response
Log SocketEngine: Sending ws:  as type: 5
Log SocketEngine: Got message: 6
Log SocketEngine: Flushing probe wait
Log SocketEngine: Got message: 420["authorizationError",{}]
Log SocketParser: Parsing 20["authorizationError",{}]
Log SocketParser: Decoded packet as: SocketPacket {type: 2; data: [authorizationError, {
}]; id: 0; placeholders: -1; nsp: /}
Log SocketIOClient: Handling event: authorizationError with data: (
        {
    }
)

Any help would be greatly appreciated. The exact same sequence of code works with another web socket library. I am just authenticating after connecting. I can share that piece of code if requested as well

nuclearace commented 9 years ago

Have you tried debugging the server side and see what the server is actually getting vs what it's expecting

danipralea commented 9 years ago

Yes. This is currently working (sorry I'm pasting another library's code):

NSDictionary * parameters = [NSDictionary dictionaryWithObject:token forKey:@"token"];
NSArray * parametersArray = [NSArray arrayWithObject:parameters];

[SIOSocket socketWithHost:serverURL response: ^(SIOSocket *socket) {
    self.socket = socket;

    self.socket.onConnect = ^ () {
    if ([GabAuthenticatedUser sharedUser].token) {
        NSLog(@"SIOSocket : web socket connected. Authenticating with parameters : %@", parameters);
        [socket emit: @"authenticate" args:parametersArray];
    }
    };

    self.socket.onDisconnect = ^ () {
        NSLog(@"SIOSocket : web socket disconnected!");
    };

    self.socket.onError = ^(NSDictionary* error) {
        NSLog(@"SIOSocket : error connecting to web socket : %@", error);
    };
}];

This is perfectly functional, but I'm trying to move away from this library, since it's not supported anymore and it lacks the functionality that I want (and Socket.IO library has)

nuclearace commented 9 years ago

Instead of using emitWithAck, does it work with just emit?

danipralea commented 9 years ago

Yes sir, it works. I wonder why have I not thought about that. (may be that a bug has slipped in though?) Thank you so much!

danipralea commented 9 years ago

Altough the on: event is not getting the callback as well. So basically no feedback for authenticating.

nuclearace commented 9 years ago

Is this server actually sending an event called authenticate?

danipralea commented 9 years ago

I don't know how the server works to be honest. But these are the logs:

SocketIO : socket connected
Log SocketIOClient: Adding handler for event: authenticate
Log SocketIOClient: Emitting: 2["authenticate",{"token":"xxxxxxx"}]
Log SocketEngine: Got polling response
Log SocketEngine: Got message: 6
Log SocketEngine: Sending ws:  as type: 5
Log SocketEngine: Flushing probe wait
Log SocketEngine: Writing ws: 2["authenticate",{"token":"xxxxxxx"}] has data: 0
Log SocketEngine: Sending ws: 2["authenticate",{"token":"xxxxxxx"}] as type: 4
Log SocketEngine: Got message: 42["welcome",{"type":"welcome","data":"Welcome Pralea Danut"}]
Log SocketParser: Parsing 2["welcome",{"type":"welcome","data":"Welcome Pralea Danut"}]
Log SocketParser: Decoded packet as: SocketPacket {type: 2; data: [welcome, {
    data = "Welcome Pralea Danut";
    type = welcome;
}]; id: -1; placeholders: -1; nsp: /}
Log SocketIOClient: Handling event: welcome with data: (
        {
        data = "Welcome Pralea Danut";
        type = welcome;
    }
)
SocketIO : any event : SocketAnyEvent: Event: welcome items: Optional((
        {
        data = "Welcome Pralea Danut";
        type = welcome;
    }
))
nuclearace commented 9 years ago

It doesn't look like the server is sending an authenticate event, just welcome.

danipralea commented 9 years ago

so the type needs to be authenticate?

nuclearace commented 9 years ago

You should add an event handler for welcome

danipralea commented 9 years ago

Thank you. I have added that and it works. One last step: I am trying to subscribe to an incoming tweets channel but it doesn't work.

I have tried either with on:, once:, emit: or emitWithAck: and nothing of these options work. This is the code:

[socket on:@"feed" callback:^(NSArray * array, SocketAckEmitter * ack) {
      NSLog(@"new content : %@", array);
}];
[socket emit:@"join:gab" withItems:@[parameters]];

//[socket once:@"feed" callback:^(NSArray * array, SocketAckEmitter * ack) {
//    NSLog(@"new content : %@", array);
//}];
//[socket emitWithAck:@"join:gab" withItems:parameters];

Logs are the same (it eventually disconnects):

Log SocketIOClient: Adding handler for event: join:gab
Log SocketIOClient: Emitting: 2["join:gab",[{"gab":"560c4df2bfd98ae56f4e8cae"}]]
Log SocketEngine: Writing ws: 2["join:gab",[{"gab":"560c4df2bfd98ae56f4e8cae"}]] has data: 0
Log SocketEngine: Sending ws: 2["join:gab",[{"gab":"560c4df2bfd98ae56f4e8cae"}]] as type: 4
Log SocketEngine: Writing ws:  has data: 0
Log SocketEngine: Sending ws:  as type: 2
Log SocketEngine: Got message: 3
Log SocketEngine: Writing ws:  has data: 0
Log SocketEngine: Sending ws:  as type: 2
Log SocketEngine: Got message: 3
Log SocketEngine: Writing ws:  has data: 0
Log SocketEngine: Sending ws:  as type: 2
Log SocketEngine: Got message: 3
Log SocketEngine: Writing ws:  has data: 0
Log SocketEngine: Sending ws:  as type: 2
Log SocketEngine: Got message: 3
Log SocketEngine: Writing ws:  has data: 0
Log SocketEngine: Sending ws:  as type: 2
Log SocketEngine: Got message: 3
Log SocketEngine: Writing ws:  has data: 0
Log SocketEngine: Sending ws:  as type: 2
Log SocketEngine: Got message: 3
Log SocketEngine: Writing ws:  has data: 0
Log SocketEngine: Sending ws:  as type: 2
Log SocketEngine: Got message: 3
Log SocketEngine: Writing ws:  has data: 0
Log SocketEngine: Sending ws:  as type: 2
Log SocketEngine: Got message: 3
Log SocketIOClient: Handling event: reconnect with data: (
    "Socket Disconnected"
)

Am I missing something? Do I need to serialize it in JSON? Any help would be greatly appreciated.

Thanks in advance!

nuclearace commented 9 years ago

Sounds more like a problem with not understanding the api you're working with.

danipralea commented 9 years ago

It may very well be the case, since it's my first time working with it :smile: or any other web socket library. Is there any chance you can be more specific? Any resources or lead can help :smiley:

nuclearace commented 9 years ago

I don't know the API of the server you're trying to use the library with

danipralea commented 9 years ago

Does it help knowing that this piece of code worked?:

SIOSocket * socket = [[GabService sharedService] socket];
[socket emit: @"join:gab" args: @[parameters]];
[socket on:@"feed" callback:^(NSArray *args) {
    NSDictionary * item = [args firstObject];
    NSDictionary * feedItemDictionary = [item valueForKey:@"feedItem"];
    NSLog(@"new feed item : %@", feedItemDictionary);
}];

My problem with this library is the duplicate data that results in multiple subscriptions or random connection losses. I saw that your library has the once: function that solves exactly my problem, and together with acknowledgments (also functionality that the SIOSocket library doesn't have) I can solve all of my issues. All I need to do is to make this final subscribe/emit to work and actually receive the content I was previously receiving.

nuclearace commented 9 years ago

Not really, I would just say that whoever thought that having join:gab as an event probably shouldn't be doing API design. From what you're showing me, it doesn't look like there's a problem with the client, more a problem with the API that you're trying to work with. So if you can show me a case where it's using the correct API and is still breaking I'll look into it more deeply.

danipralea commented 9 years ago

@nuclearace I have switched to Swift and I'm receiving this when trying to authenticate:

Log SocketParser: Decoded packet as: SocketPacket {type: 2; data: [authorizationError, {
    message = "jwt must be provided";
    name = JsonWebTokenError;
}]; id: 5; placeholders: -1; nsp: /}
nuclearace commented 9 years ago

I would say that's a problem with how you're working with the API again

danipralea commented 9 years ago

Actually, it's a problem for how the library is ported to Objective-C. I had extra hours to waste and figure out that on Swift you can send AnyObject, which means you can send a key-value pair (dictionary), but the way it was ported to Objective-C, parameters are accepted only as

NSArray :

/// Same as emit, but meant for Objective-C
- (void)emit:(NSString * __nonnull)event withItems:(NSArray * __nonnull)items;

vs.

public func emit(event: String, _ items: AnyObject...)
nuclearace commented 9 years ago

Yeah, the Swift API is designed to be more like the JavaScript API