Authored by 钱兢安

socket加密验证 review by 盖建秋

... ... @@ -16,5 +16,7 @@
#import "UIViewAdditions.h"
#import "YHAssistant.h"
#import "UtilsMacros.h"
#import "M16Model.h"
#import "APIStringMacros.h"
#endif
... ...
... ... @@ -5,6 +5,8 @@
// Created by Arthur on 16/6/14.
// Copyright © 2016年 YOHO. All rights reserved.
//
#define kIphonePrivate @"a85bb0674e08986c6b115d5e3a4884fa"
#define SOCKET_LIVE_TIMEOUT 10
#import "GCDAsyncSocket+SocketHandler.h"
... ... @@ -13,16 +15,17 @@
- (BOOL)writeDataWithParams:(NSDictionary *)params tag:(long)tag
{
NSError *error;
NSData *data = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:&error];
NSMutableDictionary *dic = [self encodeParams:params];//md5加密
NSData *data = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&error];
NSMutableData *mutaData = [NSMutableData dataWithData:data];
[mutaData appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
// DLog(@"发送:%@",[[NSString alloc] initWithData:mutaData encoding:NSUTF8StringEncoding]);
if (mutaData) {
[self writeData:mutaData withTimeout:10 tag:tag];
[self writeData:mutaData withTimeout:SOCKET_LIVE_TIMEOUT tag:tag];
[self readDataWithTimeout:-1 tag:tag];
return YES;
} else {
// DLog(@"请求序列化错误:%@", error);
DLog(@"请求序列化错误:%@", error);
return NO;
}
}
... ... @@ -56,8 +59,35 @@
}
}
}
// DLog(@"服务器返回数据序列化错误:%@", error);
DLog(@"服务器返回数据序列化错误:%@", error);
}
}
// md5加密
- (NSMutableDictionary *)encodeParams:(NSDictionary *)parameters
{
NSMutableDictionary *params = [[NSMutableDictionary alloc] initWithDictionary:parameters];
[params setObject:kIphonePrivate forKey:@"private_key"];
NSArray *allKeys = [params allKeys];
NSArray *sortedArray = [allKeys sortedArrayUsingSelector:@selector(compare:)];
NSMutableArray *strings = [NSMutableArray array];
for (NSString *key in sortedArray) {
id value = [params objectForKey:key];
if ([value isKindOfClass:[NSString class]]) {
value = [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
value = [value stringByReplacingOccurrencesOfString:@"\n" withString:@""];
value = [value stringByReplacingOccurrencesOfString:@"\t" withString:@""];
value = [value stringByReplacingOccurrencesOfString:@"\r" withString:@""];
}
[params setObject:value forKey:key];
[strings addObject:[NSString stringWithFormat:@"%@=%@", key, value]];
}
NSString *source = [strings componentsJoinedByString:@"&"];
NSString *secret = [[source md5String] lowercaseString];
[params removeObjectForKey:@"private_key"];
[params setObject:secret forKey:@"secret"];
return params;
}
@end
... ...
... ... @@ -237,32 +237,28 @@
}
#pragma mark --sockerserviceDelegate
- (void)userPraised:(NSString *)currentTotalNum isSelfPraise:(BOOL)isSelf
- (NSString *)formatNumer:(NSString *)number
{
NSInteger num = currentTotalNum.integerValue;
NSInteger num = number.integerValue;
NSInteger a = 0;
NSInteger b = 0;
if (num >9999) {
a = ceilf(num /10000);
b = ceilf((num - a * 10000)/ 1000);
self.emojiCountLabel.text =[NSString stringWithFormat:@"%ld.%ld万",(long)a,(long)b];
return [NSString stringWithFormat:@"%ld.%ld万",(long)a,(long)b];
}else{
self.emojiCountLabel.text =[NSString stringWithFormat:@"%@",currentTotalNum];
return [NSString stringWithFormat:@"%@",number];
}
}
- (void)userPraised:(NSString *)currentTotalNum isSelfPraise:(BOOL)isSelf
{
self.emojiCountLabel.text =[self formatNumer:currentTotalNum];
}
- (void)currentPeopleNumber:(NSString *)peopleNumber
{
NSInteger num = peopleNumber.integerValue;
NSInteger a = 0;
NSInteger b = 0;
if (num >9999) {
a = ceilf(num /10000);
b = ceilf((num - a * 10000)/ 1000);
self.onlineCountLabel.text =[NSString stringWithFormat:@"%ld.%ld万人在线",(long)a,(long)b];
}else{
self.onlineCountLabel.text =[NSString stringWithFormat:@"%@人在线",peopleNumber];
}
self.onlineCountLabel.text =[NSString stringWithFormat:@"%@人在线",[self formatNumer:peopleNumber]];
}
- (void)livePalyEnd:(NSString *)audienceNums likeNums:(NSString *)likeNums videoLen:(NSString *)videoLen
... ... @@ -270,7 +266,11 @@
}
- (void)liveOnlineNums:(NSString *)onlineNums likes:(NSString *)likes
{
self.emojiCountLabel.text =[self formatNumer:likes];
self.onlineCountLabel.text =[NSString stringWithFormat:@"%@人在线",[self formatNumer:onlineNums]];
}
#pragma mark - Publisher delegate methods...
... ...
... ... @@ -9,9 +9,6 @@
#import <Foundation/Foundation.h>
#import "YH_BarrageViewController.h"
#import "M16Service.h"
#import "M16Model.h"
#import "Macros.h"
#import "YHAssistant.h"
typedef NS_ENUM(NSInteger, SOCKET_TAG) {
SOCKET_TAG_EOR = -1,
... ... @@ -26,6 +23,7 @@ typedef NS_ENUM(NSInteger, SOCKET_TAG) {
SOCKET_TAG_NotifyPeopleNumber = 10, //服务器通知当前在线人数
SOCKET_TAG_EndPlay = 11, //结束播放
SOCKET_TAG_NotifyEndPlay = 12, //服务器通知结束播放
SOCKET_TAG_NotifyOnlineAndLikes = 13, //服务器通知点赞数和在线人数
};
@protocol YH_SocketServiceDelegate <NSObject>
... ... @@ -33,7 +31,7 @@ typedef NS_ENUM(NSInteger, SOCKET_TAG) {
- (void)userPraised:(NSString *)currentTotalNum isSelfPraise:(BOOL)isSelf;
- (void)currentPeopleNumber:(NSString *)peopleNumber;
- (void)livePalyEnd:(NSString *)audienceNums likeNums:(NSString *)likeNums videoLen:(NSString *)videoLen;
- (void)liveOnlineNums:(NSString *)onlineNums likes:(NSString *)likes;
@end
@interface YH_SocketService : NSObject
... ... @@ -70,6 +68,6 @@ typedef NS_ENUM(NSInteger, SOCKET_TAG) {
-(void)logout;
//手动释放timer
- (void)reset;
//- (void)reset;
@end
... ...
... ... @@ -9,17 +9,17 @@
#import "YH_SocketService.h"
#import "GCDAsyncSocket+SocketHandler.h"
#define TimeIntervalForHeartBeat 59
#define SOCKET_COMMAND @"cmd"
#define SOCKET_CONNECT_MAX_COUNT 9
@interface YH_SocketService ()<GCDAsyncSocketDelegate>
{
GCDAsyncSocket *_socket;
NSTimer *_heartBeatTimer; // ❤️
BOOL _hasLoginWithNameSuccessed;
}
@property (nonatomic, strong) NSTimer *connectTimer;
@property (nonatomic, strong) NSTimer *heartBeatTimer; // ❤️
@property (nonatomic, strong) GCDAsyncSocket *socket;
@end
... ... @@ -30,24 +30,69 @@
{
self = [super init];
if (self) {
_socket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
_heartBeatTimer = [NSTimer scheduledTimerWithTimeInterval:TimeIntervalForHeartBeat target:self selector:@selector(_heartbeat) userInfo:nil repeats:YES];
self.socket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
self.heartBeatTimer = [NSTimer scheduledTimerWithTimeInterval:TimeIntervalForHeartBeat target:self selector:@selector(_heartbeat) userInfo:nil repeats:YES];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkReachabilityDidChange:) name:AFNetworkingReachabilityDidChangeNotification object:nil];
}
return self;
}
- (void)reset
- (NSString *)getProperIPWithAddress:(NSString *)ipAddr port:(UInt32)port
{
DLog(@"socket service reset!!");
if (_heartBeatTimer) {
[_heartBeatTimer invalidate];
_heartBeatTimer = nil;
NSError *addresseError = nil;
NSArray *addresseArray = [GCDAsyncSocket lookupHost:ipAddr
port:port
error:&addresseError];
if (addresseError) {
NSLog(@"");
}
NSString *ipv6Addr = @"";
for (NSData *addrData in addresseArray) {
if ([GCDAsyncSocket isIPv6Address:addrData]) {
ipv6Addr = [GCDAsyncSocket hostFromAddress:addrData];
}
}
if (ipv6Addr.length == 0) {
ipv6Addr = ipAddr;
}
return ipv6Addr;
}
//网络发生变化时重连
- (void)networkReachabilityDidChange:(NSNotification *)notification
{
[self reConnect];
}
- (void)reConnect
{
[_socket disconnect];
self.socket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
[self connectToHostRepeat];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
//- (void)reset
//{
// DLog(@"socket service reset!!");
// if (_heartBeatTimer) {
// [_heartBeatTimer invalidate];
// _heartBeatTimer = nil;
// }
//
// [_socket disconnect];
//}
#pragma mark - Private Methods
- (void)_heartbeat{
... ... @@ -61,13 +106,17 @@
NSDictionary *params = @{@"cmd":@(SOCKET_TAG_HEARTBEAT),
@"msg":@"heartbeat",
@"msg":@"heart_ios",
@"room":MakeStringNotNil(self.room),
};
[_socket writeDataWithParams:params tag:SOCKET_TAG_SEND_MSG];
[_socket readDataWithTimeout:1.0 tag:1];
// [self loginToServer];
// [self listenData];
//心跳并判断是否已经断掉
if (![_socket isConnected]) {
[self reConnect];
}
}
#pragma mark - Service
... ... @@ -81,7 +130,6 @@
[[NSRunLoop mainRunLoop] addTimer:self.connectTimer forMode:NSRunLoopCommonModes];
} else {
NSLog(@"connent success!");
[self loginToServer];
}
} else {
NSLog(@"get addressList failed!");
... ... @@ -133,11 +181,13 @@
- (BOOL)connectToHost:(NSString *)host onPort:(uint16_t)port
{
NSString *hostProper = [self getProperIPWithAddress:host port:port];
NSError *socketConnectError = nil;
NSAssert(_socket, @"You must init YH_SocketService first!");
[_socket connectToHost:host onPort:port error:&socketConnectError];
[_socket connectToHost:hostProper onPort:port error:&socketConnectError];
if (socketConnectError) {
DLog(@"connect host error: %@", [socketConnectError localizedDescription]);
... ... @@ -159,6 +209,7 @@
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
DLog(@"socket connect success!");
[self loginToServer];
[self listenData];
}
... ... @@ -181,7 +232,7 @@
switch (tag) {
case SOCKET_TAG_LOGIN:
{
[self _heartbeat];
// [self _heartbeat];
}
break;
... ... @@ -225,6 +276,9 @@
case SOCKET_TAG_RESIVE_MSG:
case SOCKET_TAG_USER_JOIN:
{
if (resDic && [resDic.allKeys containsObject:@"uid"] && [resDic[@"uid"] isEqualToString:self.uid] && [self.uid notNilOrEmpty]) {
_hasLoginWithNameSuccessed = YES;
}
[self.barrageViewController insertItem:resDic];
}
break;
... ... @@ -232,8 +286,8 @@
{
if ([self.delegate respondsToSelector:@selector(userPraised:isSelfPraise:)] && [resDic.allKeys containsObject:@"msg"]) {
yh_dispatch_execute_in_main_queue(^{
[self.delegate userPraised:resDic[@"msg"] isSelfPraise:([resDic[@"uid"] isEqualToString:self.uid])];
// BOOL isSelfPraise =(resDic[@"deviceToken"] && [resDic[@"deviceToken"] isEqualToString:[GVUserDefaults standardUserDefaults].deviceTokenString]);
[self.delegate userPraised:resDic[@"msg"] isSelfPraise:NO];
});
}
}
... ... @@ -242,7 +296,7 @@
{
if ([self.delegate respondsToSelector:@selector(currentPeopleNumber:)] && [resDic.allKeys containsObject:@"msg"]) {
yh_dispatch_execute_in_main_queue(^{
[self.delegate currentPeopleNumber:resDic[@"msg"]];
[self.delegate currentPeopleNumber:resDic[@"onlineNums"]];
});
}
}
... ... @@ -256,6 +310,15 @@
}
}
break;
case SOCKET_TAG_NotifyOnlineAndLikes:
{
if ([self.delegate respondsToSelector:@selector(liveOnlineNums:likes:)]) {
yh_dispatch_execute_in_main_queue(^{
[self.delegate liveOnlineNums:resDic[@"onlineNums"] likes:resDic[@"likeNums"]];
});
}
}
break;
default:
break;
}
... ... @@ -288,10 +351,10 @@
- (void)loginToServer
{
NSDictionary *params = @{@"cmd":@(SOCKET_TAG_LOGIN),
@"uid":MakeStringNotNil(self.uid),
@"uid":(_hasLoginWithNameSuccessed?@"":MakeStringNotNil(self.uid)),
@"room":MakeStringNotNil(self.room),
@"name":MakeStringNotNil(self.userName),
@"avatar":MakeStringNotNil(self.avartar)
@"name":(_hasLoginWithNameSuccessed?@"":MakeStringNotNil(self.userName)),
@"avatar":(_hasLoginWithNameSuccessed?@"":MakeStringNotNil(self.avartar)),
};
[_socket writeDataWithParams:params tag:SOCKET_TAG_LOGIN];
... ... @@ -317,7 +380,8 @@
NSDictionary *params = @{@"cmd":@(SOCKET_TAG_PRAISE),
@"uid":MakeStringNotNil(self.uid),
@"msg":@"",
@"room":MakeStringNotNil(self.room)
@"room":MakeStringNotNil(self.room),
@"deviceToken":@"",
};
[_socket writeDataWithParams:params tag:SOCKET_TAG_SEND_MSG];
}
... ...