Closed jonathannorris closed 9 years ago
@iliu I think this gets us all the way there.
@jonathannorris, great job! Thank you.
@jonathannorris looks good from source inspection!
Awesome.
The only question I had for you guys was waitUntilDone on performSelector:onThread:withObject:waitUntilDone:
I set it to NO right now as it probably doesn't make sense to have the calling thread wait because the calls to JS are async anyway.
@pcperini can you take a look at this pull request, it solves the threading issues many people have been seeing.
@jonathannorris my application(iOS8 on iPhone 5s) has become non-responsive after updating to the SIOSocket library with thread fixes. Neither the client is able to send (emit) messages to the server and nor is it able to receive(on) messages from server. Any idea why this could be happening? Do you suggest me to change anything sepcifically in my code?
@anuradhavasudeva interesting, this thread fix was implemented exactly to solve this problem. Are you sure you don't JSON creation errors?
@zulkis I do not see any crashes or errors...in fact, the execution goes thru emit call...
Odd I haven't seen any errors like this. If the emit's are still be sent to the JS, maybe its a connection issue or an issue in the JS thread?
@jonathannorris I guess if the issue in JS thread - we will be informed about it in exception callback block. For me it works like a charm right after I found this issue with threading and @jonathannorris wrapped it in a big commit. @anuradhavasudeva are you sure, that your connection to server established?
@anuradhavasudeva, when you say non responsive is it the UI that's non-responsive, like a hang? Since all the callbacks are now dispatched to the main thread to be handled, you could be blocking the main thread in the callbacks, or something else could be blocking the main thread or deadlocking.
@jonathannorris @iliu @zulkis thanks for the response. Server runs on socket 1.3.3 and I was using SIOSocket earlier version and things were going smooth except for the connect/disconnect issue. Now, I updated the SIOSocket and what happens is - Client opens socket using a singleton class...server gets a connection request. Success. Now, Client prepares parameters for emit. Creates array of parameters and does emit BUT this time server doesn't receive emit!! Some code pasted here fyr
My singleton class looks like this :
(SIOSocket *)SIOsocket {
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; [defaults setInteger:0 forKey:@"SocketOpened"];
if (!_SIOsocket) {
_SIOsocket = [[SIOSocket alloc] init];
[defaults setInteger:1 forKey:@"SocketOpened"];
NSLog(@"new socket created");
} else { NSLog(@"working with old socket"); } return _SIOsocket; }
SocketKeeperSingleton *SingletonSocket = [SocketKeeperSingleton sharedInstance];
SIOSocket *MySocket = [SingletonSocket SIOsocket];
NSArray * dataPieces = [[NSArray alloc] initWithObjects: [NSString stringWithFormat: @"%@", [defaults objectForKey:@"NickName"] ], [NSString stringWithFormat: @"%@", [defaults objectForKey:@"PhoneNumber"] ], [NSString stringWithFormat: @"%@", [defaults objectForKey:@"Gender"] ], [NSString stringWithFormat: @"%@", [defaults objectForKey:@"CLatitude"]], [NSString stringWithFormat: @"%@", [defaults objectForKey:@"CLongitude"]], [NSString stringWithFormat: @"%@", [defaults objectForKey:@"country"]], [NSString stringWithFormat: @"%@", [defaults objectForKey:@"postalCode"]], [NSString stringWithFormat: @"%@", [defaults objectForKey:@"administrativeArea"]], [NSString stringWithFormat: @"%@", [defaults objectForKey:@"subAdministrativeArea"]], [NSString stringWithFormat: @"%@", [defaults objectForKey:@"locality"]], [NSString stringWithFormat: @"%@", [defaults objectForKey:@"subLocality"]], [NSString stringWithFormat: @"%@", [defaults objectForKey:@"thoroughfare"]], [NSString stringWithFormat: @"%@", [defaults objectForKey:@"subThoroughfare"]], [NSString stringWithFormat: @"regionTBD", [defaults objectForKey:@"region"]], [NSString stringWithFormat: @"%@", [defaults objectForKey:@"PhoneId"]], [NSString stringWithFormat: @"%@", [defaults objectForKey:@"UserMood"]], [NSString stringWithFormat: @"V1", [defaults objectForKey:@"ClientVersion"]], [NSString stringWithFormat: @"%@", [defaults objectForKey:@"deviceToken"]], [NSString stringWithFormat: @"iPhone", [defaults objectForKey:@"Device"]], [NSString stringWithFormat: @"%@", [defaults objectForKey:@"age"]],
nil
];
[ MySocket emit:@"join"
args: dataPieces];
@anuradhavasudeva I think your issues is you are not initializing SIOSocket properly, take a look at SIOSocket.h you need to use one of the two generator functions.
Here is an example of how I initialize it:
[SIOSocket socketWithHost:@"https://your.socket.path" response:^(SIOSocket *socket) {
self.socket = socket;
__weak typeof(self) weakSelf = self;
self.socket.onConnect = ^() {
NSLog(@"Socket Connected!");
weakSelf.isConnected = YES;
[weakSelf connectToSocketRoom];
};
self.socket.onConnectError = ^(NSDictionary* error) {
NSLog(@"Socket Connection Error: %@", error);
weakSelf.isConnected = NO;
[weakSelf retrySocketConnection];
};
self.socket.onDisconnect = ^() {
NSLog(@"Socket Disconnected");
weakSelf.isConnected = NO;
weakSelf.connectingSocketPath = nil;
[weakSelf retrySocketConnection];
};
self.socket.onError = ^(NSDictionary* error) {
NSLog(@"Socket Error: %@", error);
[weakSelf retrySocketConnection];
};
[self.socket on:@"event" callback:^(id data) {
NSLog(@"Got Socket event, data: %@", data);
}];
}];
(also take a look at github markdown to format your code: https://guides.github.com/features/mastering-markdown/)
@jonathannorris - Oops! sorry for not including the initialisation code. Here is what I'm doing for initialisation: (Please note, the code was working before replacing the library)
[MySocket socketWithHost: @"http://bubble.trafficmanager.net:80" response: ^(SIOSocket *socket)
{
self.socket = socket;
self.socket.onConnect = ^ () {
NSLog(@"connected");
};
self.socket.onDisconnect = ^ () {
NSLog(@"disconnected");
};
self.socket.onError = ^(NSDictionary* error) {
NSLog(@"%@", error);
};
if(!loggedin)
{
NSArray * dataPieces = [[NSArray alloc] initWithObjects:
[NSString stringWithFormat: @"%@", [defaults objectForKey:@"NickName"] ],
[NSString stringWithFormat: @"%@", [defaults objectForKey:@"PhoneNumber"] ],
[NSString stringWithFormat: @"%@", [defaults objectForKey:@"Gender"] ],
[NSString stringWithFormat: @"%@", [defaults objectForKey:@"CLatitude"]],
[NSString stringWithFormat: @"%@", [defaults objectForKey:@"CLongitude"]],
[NSString stringWithFormat: @"%@", [defaults objectForKey:@"country"]],
[NSString stringWithFormat: @"%@", [defaults objectForKey:@"postalCode"]],
[NSString stringWithFormat: @"%@", [defaults objectForKey:@"administrativeArea"]],
[NSString stringWithFormat: @"%@", [defaults objectForKey:@"subAdministrativeArea"]],
[NSString stringWithFormat: @"%@", [defaults objectForKey:@"locality"]],
[NSString stringWithFormat: @"%@", [defaults objectForKey:@"subLocality"]],
[NSString stringWithFormat: @"%@", [defaults objectForKey:@"thoroughfare"]],
[NSString stringWithFormat: @"%@", [defaults objectForKey:@"subThoroughfare"]],
[NSString stringWithFormat: @"regionTBD", [defaults objectForKey:@"region"]],
[NSString stringWithFormat: @"%@", [defaults objectForKey:@"PhoneId"]],
[NSString stringWithFormat: @"%@", [defaults objectForKey:@"UserMood"]],
[NSString stringWithFormat: @"V1", [defaults objectForKey:@"ClientVersion"]],
[NSString stringWithFormat: @"%@", [defaults objectForKey:@"deviceToken"]],
[NSString stringWithFormat: @"iPhone", [defaults objectForKey:@"Device"]],
[NSString stringWithFormat: @"%@", [defaults objectForKey:@"age"]],
nil
];
[ MySocket emit:@"join"
args: dataPieces];
}];
I printed the string before emit and it shows :
objc_socket.emit('join', 'juggling', '96666', 'Male', '48.4052', '2.68482', 'France', '77300', 'Île-de-France', 'Seine-et-Marne', 'Fontainebleau', '(null)', 'Route de l'Ermitage', '(null)', 'regionTBD', 'E1C3FED7-FE4A-413D-AD53-87FBEC2361FD', 'what's happening now?', 'V1', '<5f83df2d d5c6a5c3 b4cc35f6 96c94199 c85392b8 516ec850 d9c989d6 4311e39b>', 'iPhone', '16');
Server connect, disconnect is successful. Is this library tested with 1.3.3 socket IO on the server?
Anyone here knows how to fix the issue I'm facing? I'm unable to make progress on my Project..
@anuradhavasudeva, how you could emit:args: on a class? I see that you socketWithHost:response: on MySocket, which is class, then you do emit:args: on MySocket again.
Another issue: Try emit after you get onConnect callback. So:
self.socket.onConnect = ^ () {
NSLog(@"connected");
self.socket.emit('join', 'juggling', '96666', 'Male', '48.4052', '2.68482', 'France', '77300', 'Île-de-France', 'Seine-et-Marne', 'Fontainebleau', '(null)', 'Route de l'Ermitage', '(null)', 'regionTBD', 'E1C3FED7-FE4A-413D-AD53-87FBEC2361FD', 'what's happening now?', 'V1', '<5f83df2d d5c6a5c3 b4cc35f6 96c94199 c85392b8 516ec850 d9c989d6 4311e39b>', 'iPhone', '16');
};
@zulkis thanks for the comments. I'm using a singleton class and Mysocket is defined as follows: SIOSocket *MySocket = [SingletonSocket SIOsocket]; I get a singleton socket here. I tried to put this code inside onConnect block and also used socket object instead of singleton socket still it doesn't work!
@anuradhavasudeva did you try to debug emit call? Did it successfully JSON it? What about jsException handler in SIOSocket? Did it show anything?
@zulkis I've written NSLog statements in error and exception handlers...They are not executed. It means emit is OK.
I have enabled log after emit as shown below:
NSString* script = [NSString stringWithFormat: @"objc_socket.emit(%@);", [arguments componentsJoinedByString: @", "]];
[self performSelector:@selector(evaluateScript:) onThread:_thread withObject:[script copy] waitUntilDone:NO];
NSLog(@"emit script is : %@", script);
It prints the following:
emit script is : objc_socket.emit('join', 'zombies ', '999999993', 'Male', '37.3327', '-122.061', 'United States', '95014', 'CA', 'Santa Clara', 'Cupertino', 'Homestead', 'I-280 N', '(null)', 'regionTBD', 'BA440682-A758-4CA6-ABA8-1DA1416C71E1', 'what's happening now?', 'V1', '(null)', 'iPhone', '19');
@zulkis @jonathannorris @iliu - interesting update is: I sent an event to the server that requires no parameters and it worked. Do you see any obvious issue with the param list(mentioned above) i'm sending?
@zulkis @jonathannorris @iliu The issue was with - apostrophe!! If any parameter includes apostrophe in the text then the emit fails! I have solved it. Now I'm not getting call back from the server (on function) any thoughts?
Old code base with earlier SIOSocket library has the following on function
- (void)on:(NSString *)event callback:(void (^)(id))function -- V1
this used to work and still works with the old SIOSocket library... but the moment i change to the new library on function with the following signature -
- (void)on:(NSString *)event callback:(void (^)(SIOParameterArray *args))function { -- V2
call back doesn't work and strangely putting back the old function(V1) is not helping ...
Builds on @zulkis pull request #42 to fix threading issues #16, #36.
We store the thread created by the javascriptContext to use when calling evaluateScript, so that all calls to evaluateScript are on the same thread.
Also all callbacks are run against the main thread to ensure thread safety.