Asyncsocketdemo:asyncsocketdemo
The socket can be used to send instant messages like QQ. A long connection is required between the client and the server to send a message in the case of a long connection. The client can send a heartbeat packet to detect a long connection.
Using sockets in iOS development is generally asyncsocket with third-party libraries, and has to admit that the library is really powerful. Cocoaasyncsocket
。
When using Asyncsocket, you can do a layer of encapsulation and provide several interfaces as required. For example: Connect, disconnect, send messages, and so on. Also accept the message, the received message can be sent through notification, proxy, block, etc.
A brief introduction to the use of asyncsocket. In general, a user only needs to establish a long socket connection, so it is easy to use a singleton class.
Defining a single-column class: Lgsocketserve
LGSocketServe.h
lgsocketserve.h// asyncsocketdemo//// Created by Ligang on 15/4/3.// Copyright (c) 2015 Ligang. All rights reserved.//#import <Foundation/Foundation.h> #import "AsyncSocket.h" @interface Lgsocketserve: nsobject<asyncsocketdelegate>+ (Lgsocketserve *) Sharedsocketserve; @end
Lgsocketserve.m
lgsocketserve.m// asyncsocketdemo//// Created by Ligang on 15/4/3.// Copyright (c) 2015 Ligang. All rights reserved.//#import "LGSocketServe.h" @implementation lgsocketservestatic lgsocketserve *socketserve = nil;# pragma mark public static methods+ (Lgsocketserve *) Sharedsocketserve { @synchronized (self) { if (Socketserve = = Nil) { socketserve = [[[Self class] alloc] init]; } } return socketserve;} + (ID) Allocwithzone: (Nszone *) zone{ @synchronized (self) { if (Socketserve = = nil) { Socketserve = [Super Allocwithzone:zone]; return socketserve; } } return nil;} @end
Establishing a long socket connection
LGSocketServe.h
@property (nonatomic, strong) Asyncsocket *socket; socket// Socket Connection-(void) startconnectsocket;
Lgsocketserve.m
Set the # define HOST @ "192.168.0.1" #define PORT 8080//Set the connection timeout # time_out 20-(void) startconnectsocket{ Self.socket = [[Asyncsocket alloc] initwithdelegate:self]; [Self.socket Setrunloopmodes:[nsarray arraywithobject:nsrunloopcommonmodes]; if (![ Self socketopen:host port:port]) { }}-(Nsinteger) Socketopen: (nsstring*) addr port: (nsinteger) port{ if ( ! [Self.socket isconnected]) { Nserror *error = nil; [Self.socket connecttohost:addr onport:port withtimeout:time_out error:&error]; } return 0;}
Macros define host, PORT, Time_out, and implement the Startconnectsocket method. This time to set up a asyncsocket agent asyncsocketdelegate. When a long connection succeeds, it is called:
-(void) Onsocket: (Asyncsocket *) sock didconnecttohost: (NSString *) host port: (UInt16) port{ //This is the asynchronous return of the connection succeeded, NSLog (@ "Didconnecttohost");}
Heartbeat
LGSocketServe.h
@property (nonatomic, retain) Nstimer *hearttimer; Heartbeat Timer
Lgsocketserve.m
-(void) Onsocket: (Asyncsocket *) sock didconnecttohost: (NSString *) host port: (UInt16) port{ //This is the asynchronous return of the connection succeeded, NSLog (@ "Didconnecttohost"); Constant sending of messages via timers to detect long connections Self.hearttimer = [Nstimer scheduledtimerwithtimeinterval:2 target:self selector: @selector (Checklongconnectbyserve) Userinfo:nil Repeats:yes]; [Self.hearttimer fire];} Heartbeat connection-(void) checklongconnectbyserve{ //Send a fixed message to the server to detect a long connection nsstring *longconnect = @ "Connect is here"; NSData *data = [Longconnect datausingencoding:nsutf8stringencoding]; [Self.socket writedata:data withtimeout:1 tag:1];}
In the successful connection callback method, the timer is started and a fixed message is sent to the server every 2 seconds to detect the long connection. (This is possible depending on the needs of the server)
Disconnect Connection
1, User disconnects manually
LGSocketServe.h
Disconnect the socket connection-(void) cutoffsocket;
Lgsocketserve.m
-(void) cutoffsocket{ self.socket.userData = socketofflinebyuser; [Self.socket disconnect];}
Cutoffsocket is not attempting to reconnect after the user disconnects.
2,wifi Disconnect, Socket disconnected
Lgsocketserve.m
-(void) Onsocket: (Asyncsocket *) sock willdisconnectwitherror: (Nserror *) err{ NSLog (@ "Willdisconnectwitherror% LD err =%@ ", sock.userdata,[err description]); if (Err.code = =) { self.socket.userData = socketofflinebywificut; }}
After the WiFi disconnects, it will callback Onsocket:willdisconnectwitherror: method, Err.code = = 57, this time set self.socket.userData = Socketofflinebywificut.
Re-connect
The socket will be recalled after disconnecting:
Lgsocketserve.m
-(void) Onsocketdiddisconnect: (Asyncsocket *) sock{ NSLog (@ "7878 sorry the Connect is failure%ld", sock.userdata); C1/>if (Sock.userdata = = socketofflinebyserver) { //server dropped, re-connected [self startconnectsocket]; } else if (Sock.userdata = = Socketofflinebyuser) { //if disconnected by the user, do not re-connect return; } else if (Sock.userdata = = socketofflinebywificut) { //WiFi disconnected, do not re-connect return;} }
In the Onsocketdiddisconnect callback method, the Self.socket.userData is used to determine if a reconnection is required.
Send Message
LGSocketServe.h
Send Message-(void) SendMessage: (ID) message;
Lgsocketserve.m
Set write timeout-1 means no time-out # define write_time_out-1-(void) SendMessage: (ID) message{ //Like server sending data nsdata *cmddata = [ Message datausingencoding:nsutf8stringencoding]; [Self.socket writedata:cmddata withtimeout:write_time_out tag:1];} Callback after sending message succeeded-(void) Onsocket: (Asyncsocket *) sock Didwritedatawithtag: (long) tag{}
When the message is sent successfully, Onsocket:didwritedatawithtag is called: In this method, the message can be read.
Accept Message
Lgsocketserve.m
Set Read timeout-1 indicates that the timeout is not used # Read_time_out-1#define Max_buffer 1024//Send message after successful callback-(void) Onsocket: (Asyncsocket *) sock Didwritedatawithtag: (Long) tag{ //Read message [self.socket readdatawithtimeout:-1 buffer:nil bufferoffset:0 Maxlength:max_buffer tag:0];} Callback after receiving message success-(void) Onsocket: (Asyncsocket *) sock didreaddata: (NSData *) data withtag: (long) tag{ //server returns a larger amount of message data , which may be returned several times. So when reading a message, setting Max_buffer indicates the maximum number of reads per time, when Data.length < Max_buffer we think it is possible to accept a complete message before resolving if (Data.length < MAX _buffer) { //Receive result parsing ... Nsdictionary *dic = [nsjsonserialization jsonobjectwithdata:data options:nsjsonreadingmutableleaves Error:nil]; NSLog (@ "%@", dic); The parsed message can be sent out by notification, proxy, block, etc. } [Self.socket readdatawithtimeout:read_time_out buffer:nil bufferoffset:0 Maxlength:max_buffer tag:0];
After receiving the message to parse, and then can be sent through notification, proxy, block, etc. outgoing. In OnSocket:didReadData:withTag: Callback method needs to read the message constantly, because the volume of data is larger, the server will be returned multiple times. So we need to define a Max_buffer macro that represents the maximum number of reads per time. When Data.length < Max_buffer we think it is possible to accept a complete message before parsing.
Error handling
Lgsocketserve.m
-(void) Onsocket: (Asyncsocket *) sock willdisconnectwitherror: (Nserror *) err{ nsdata * unreaddata = [sock unreaddata ]; * * This gets the current buffer if (Unreaddata.length > 0) { [self onsocket:sock didreaddata:unreaddata witht AG:0]; * * Return as much data could be collected } else { NSLog (@ "Willdisconnectwitherror%ld err =%@", sock . Userdata,[err description]); if (Err.code = =) { self.socket.userData = socketofflinebywificut; }} }
The socket error callback Onsocket:willdisconnectwitherror: method, you can read the buffer by Unreaddata.
Use
Import #import "LGSocketServe.h"
Lgsocketserve *socketserve = [lgsocketserve sharedsocketserve];//socket disconnect before connecting before the socket connection is not broken cause flash back [socketserve Cutoffsocket];socketserve.socket.userdata = Socketofflinebyserver; [Socketserve startconnectsocket];//sends a message @ "Hello World" is just an example, depending on the message format of the server [Socketserve sendmessage:@ "Hello World"];
The above is the simple use of asyncsocket, in the actual development process will still encounter a lot of problems, welcome to add my public number iOS development: Iosdevtip, together to discuss the problems encountered in Asyncsocket.
Asyncsocketdemo:asyncsocketdemo
iOS Development Asyncsocket Use tutorial