iOS 클래식 설명의 Socket 사용 강좌
ios 원생의 socket은 사용하기에 직관적이지 않기 때문에 저는 AsyncSocket이라는 제3자 라이브러리를 사용합니다. socket의 봉인에 비교적 좋습니다. 다만 대역외 전송(out-of-band)이 없는 것 같습니다. 만약에 서버가 대역외 데이터를 보내야 한다면 다른 방법을 생각해 봐야 할 것 같습니다.
환경
AsyncSo 다운로드ckethttps://github.com/robbiehanson/CocoaAsyncSocket라이브러리, RunLoop 폴더 아래의 AsyncSocket.h, AsyncSocket.m, AsyncUdpSocket.h, AsyncUdpSocket.m 파일을 자신의 프로젝트로 복사
CFNetwork를 추가합니다.프레임워크, socket 파일 헤더 사용
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <unistd.h>
활용단어참조
1. 소켓 연결
실시간 통신의 가장 큰 특징은 실시간성이다. 기본적으로 시간 지연이나 오프라인이 느껴지지 않기 때문에 반드시 socket의 연결을 감시하고 검측해야 한다. 끊어질 때 다시 연결해야 한다. 만약에 사용자가 로그인을 종료하면 socket을 수동으로 닫아야 한다. 그렇지 않으면 서버에 일정한 부하를 초래할 것이다.
일반적으로 한 사용자(ios에 대해 말하자면 우리의 프로젝트에서)는 연결 중인 socket만 있을 수 있기 때문에 이 socket 변수는 반드시 전역적이어야 한다. 여기서 단례나 AppDelegate를 사용하여 데이터 공유를 할 수 있다. 본고는 단례를 사용한다.연결된 socket 대상에 대해 다시 연결 작업을 하면 이상 (연결된 socket에 연결할 수 없음) 프로그램이 붕괴되기 때문에 socket에 연결하기 전에 socket 대상의 연결 상태를 판단해야 합니다
socket을 사용하여 실시간 통신을 하려면 서버에 하트비트 팩을 보내고 일정 시간마다 서버에 긴 연결 지령을 보내는 것도 필수적이다. (지령이 유일하지 않고 서버 측에서 지정한다. socket을 사용하여 메시지를 보내는 것을 포함하고 보내는 데이터와 형식은 모두 서버에서 지정한다.) 서버의 복귀 메시지를 받지 못하면 AsyncSocket은 연결을 잃은 메시지를 받는다.우리는 연결을 잃은 리셋 방법에서 다시 연결할 수 있다.
Singleton이라는 단일 예제를 먼저 만듭니다.
Singleton.h
// Singleton.h
#import "AsyncSocket.h"
#define DEFINE_SHARED_INSTANCE_USING_BLOCK(block) \
static dispatch_once_t onceToken = 0; \
__strong static id sharedInstance = nil; \
dispatch_once(&onceToken, ^{ \
sharedInstance = block(); \
}); \
return sharedInstance; \
@interface Singleton : NSObject
+ (Singleton *)sharedInstance;
@end
Singleton.m
+(Singleton *) sharedInstance
{
static Singleton *sharedInstace = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstace = [[self alloc] init];
});
return sharedInstace;
}
이렇게 하나의 단례가 만들어졌다
있다h 파일의 생명socket 변수
@property (nonatomic, strong) AsyncSocket *socket; // socket
@property (nonatomic, copy ) NSString *socketHost; // socket Host
@property (nonatomic, assign) UInt16 socketPort; // socket prot
다음은
,
,
연결 (긴 연결)있다h 파일의 성명 방법, 성명 에이전트
<AsyncSocketDelegate>
-(void)socketConnectHost;// socket
있다m에서 실행됩니다. 연결할 때host와port는 모두 서버에서 지정합니다. 자신이 쓴 서버가 아니라면 서버 측 개발자와 교류하십시오.
// socket
-(void)socketConnectHost{
self.socket = [[AsyncSocket alloc] initWithDelegate:self];
NSError *error = nil;
[self.socket connectToHost:self.socketHost onPort:self.socketPort withTimeout:3 error:&error];
}
가슴이 두근거리다
심장 박동은 타이머를 통해singleton에서 이루어진다.h에서 타이머 선언
@property (nonatomic, retain) NSTimer *connectTimer; //
있다m에서 연결 성공 리셋 방법을 실현하고 이 방법에서 타이머를 초기화하여 심박수를 보내면 서버에 데이터를 보낼 때 설명합니다
#pragma mark -
-(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
NSLog(@"socket ");
// 30s
self.connectTimer = [NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(longConnectToSocket) userInfo:nil repeats:YES];// longConnectToSocket
[self.connectTimer fire];
}
2. socket 연결 해제 및 재연결
연결 해제
연결이 끊기는 몇 가지 상황이 있습니다. 서버가 끊어지고 사용자가 주동적으로 cut를 합니다. QQ의 다른 장치 로그인이 끊기는 경우도 있습니다. 그런 경우를 막론하고 우리는 socket 리셋 방법으로 우리에게 되돌아오는 메시지를 받을 수 있습니다. 만약에 사용자가 로그인을 종료하거나 프로그램이 종료하기 위해 수동으로 cut를 해야 한다면 우리는 cut 전에 socket의 사용자 데이터에 사용자 종료라고 표시할 값을 부여합니다.이렇게 하면 우리는 끊긴 메시지를 받았을 때 도대체 어떤 원인으로 인해 오프라인 상태가 되었는지 판단할 수 있다
있다h 파일에서 열거 형식을 설명합니다
enum{
SocketOfflineByServer,// , 0
SocketOfflineByUser, // cut
};
연결 해제 방법 선언
-(void)cutOffSocket; // socket
.m
// socket
-(void)cutOffSocket{
self.socket.userData = SocketOfflineByUser;//
[self.connectTimer invalidate]; [self.socket disconnect]; }
중련
에이전트 구현 방법
-(void)onSocketDidDisconnect:(AsyncSocket *)sock
{
NSLog(@"sorry the connect is failure %ld",sock.userData);
if (sock.userData == SocketOfflineByServer) {
// ,
[self socketConnectHost];
}
else if (sock.userData == SocketOfflineByUser) {
// ,
return;
}
}
3. socket 데이터 전송 및 수신
데이터를 보내면 위의 심장박동 연결이 완료되지 않은 방법을 보충합니다
//
-(void)longConnectToSocket{
// , @"longConnect",
NSString *longConnect = @"longConnect";
NSData *dataStream = [longConnect dataUsingEncoding:NSUTF8StringEncoding];
[self.socket writeData:dataStream withTimeout:1 tag:1];
}
cket 전송 데이터는 창고 형식으로 저장되고 모든 데이터를 한 창고에 두면 저장할 때 패키지가 붙는 현상이 발생하기 때문에 서버가 데이터를 수발할 때 내용 바이트 길이를 먼저 보내고 내용을 보내는 형식으로 데이터를 받을 때도 길이를 먼저 얻고 이 길이에 따라 창고에서 이 길이의 바이트 흐름을 읽는 경우가 많다. 만약에 이런 상황이라면데이터를 보낼 때 내용을 보내기 전에 한 길이만 보내면 됩니다. 발송 방법은 발송 내용과 마찬가지로 길이가 8이라고 가정합니다
NSData *dataStream = [@8 dataUsingEncoding:NSUTF8StringEncoding];
[self.socket writeData:dataStream withTimeout:1 tag:1];
수신 데이터는 항상 socket 메시지를 받을 수 있도록 긴 연결 방법에서 데이터를 읽습니다
[self.socket readDataWithTimeout:30 tag:0];
만약 데이터를 얻게 된다면, 리셋 방법을 호출할 것이다
-(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
// data
[self.socket readDataWithTimeout:30 tag:0];
}
4. 간단한 사용 설명
우리는 사용자가 로그인한 후 첫 번째 인터페이스에서 socket의 초기화 연결 조작을 한다. 데이터를 얻은 후에 표시해야 할 데이터를 singleton에 놓고 변수를 감청한 후에 해당하는 조작을 하면 된다. 확장이 비교적 복잡하고 실제 데이터가 없으면 설명하기 어렵다. 여러분 스스로 탐색하세요. 문제가 있으면 아래에 메시지를 남겨주세요.
[Singleton sharedInstance].socketHost = @"192.186.100.21";// host [Singleton sharedInstance].socketPort = 10045;// port // [Singleton sharedInstance].socket.userData = SocketOfflineByUser; [[Singleton sharedInstance] cutOffSocket]; // , socket , [Singleton sharedInstance].socket.userData = SocketOfflineByServer; [[Singleton sharedInstance] socketConnectHost];
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
React 구성 요소에서 소켓 이벤트 리스너가 여러 번 실행됩니다.기본적이지만 종종 간과되는 사이드 프로젝트를 하면서 배운 것이 있습니다. 이 프로젝트에는 단순히 두 가지 주요 부분이 포함되어 있습니다. 프런트 엔드: 반응 및 재료 UI 백엔드: Express, Typescript...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.