Instant Messaging: socket usage, instant messaging socket
In the previous article, I talked about the method of Instant Messaging programming. I used socket to write a communication application that imitates QQ chat. By the way, I would like to use this application to introduce the use of a socket.
The difference between socket and XMPP is that both the socket client and the server must be built on their own. XMPP has ready-made servers and clients, which makes it easy to compile and test. Therefore, XMPP has become the mainstream of Instant Messaging programming. However, socket is worth exploring because it is of personal interest.
Okay, that's all. The following is my socket application.
First, introduce the client. This is the client login interface.
Next, register
Click register --(Send a registration message to the server-the following code will introduce)
User information registered on the client is stored in the database on the server.
Enter the user name and password you just registered to log in.
Log on to the page and navigate to the AsyncSocket framework.
# Import <UIKit/UIKit. h> # import "AsyncSocket. h "typedef void (^ isSuccessBlock) (BOOL); @ interface ViewController: UIViewController {_ weak IBOutlet UIView * _ contBgView; // login VIEW _ weak IBOutlet UITextField * _ usernameField; _ weak IBOutlet UITextField * _ pwdField; _ weak IBOutlet UITableView * _ tableView; _ weak IBOutlet UIView * _ sendView; // information text _ weak IBOutlet UITextField * _ message;} @ property (nonatomic, strong) AsyncSocket * socket; // client communication object @ property (nonatomic, copy) isSuccessBlock block; // Block the message upon successful login // send the message-(IBAction) sendMessage :( UIButton *) sender; // verify the user-(IBAction) contentAction :( UIButton *) sender; // register the user-(IBAction) registerAction :( UIButton *) sender; @ end
# Import "ViewController. h "# import" MyCell. h "# import" registerViewController. h "@ interface ViewController () <UITableViewDataSource, UITableViewDelegate, AsyncSocketDelegate> // sets the communication proxy {NSMutableArray * dataArr; // stores the message NSString * username of the client and other clients; // user name after verification is passed} @ end @ implementation ViewController-(void) viewDidLoad {[super viewDidLoad]; self. title = @ "Cheep"; _ contBgView. backgroundColor = [UIColor colorWithPatt ErnImage: [UIImage imageNamed: @ "red.jpg"]; dataArr = [NSMutableArray array]; _ tableView. backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: @ "chat_bg_default.jpg"]; _ tableView. separatorStyle = UITableViewCellSeparatorStyleNone; _ tableView. rowHeight = 64; _ sendView. backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: @ "chat_bottom_textfield.png"]; // ios socket third-party framework AsyncSoc Ket introduction, connection, heartbeat, disconnection, data sending and receiving/* 1. socket Connection 2. socket disconnect and reconnect 3. socket send and receive data 4. simple instructions */if (_ socket = nil) {_ socket = [[AsyncSocket alloc] initWithDelegate: self]; // set the server address and port [_ socket connectToHost: @ "192.168.7.19" onPort: 6225 error: nil] ;}// verify the user-(IBAction) contentAction :( UIButton *) sender {/* key: value doWhat: commit (Verification mark) username: _ usernameField. text... * /// convert the string into a dictionary style package and send the NSString * d AtaStr = [NSString stringWithFormat: @ "{\" doWhat \ ": \" commit \ ", \" username \ ": \" % @ \ ", \" password \": \ "% @ \"} ", _ usernameField. text, _ pwdField. text]; NSData * data = [dataStr dataUsingEncoding: NSUTF8StringEncoding]; /* data sent to the server-1 request timeout-1 indicates that the tag is always waiting for the server to reply to the request to match the method that initiates the call in the callback method, it will not be added to the transmitted data */[_ socket writeData: data withTimeout:-1 tag: 0]; // listen to the Request Message [_ socket readDataWithTimeout:-1 tag: 0]; // The server returns the verification message _ block = ^ (BOO L result) {if (! Result) {_ usernameField. text = @ ""; _ pwdField. text = @ "";} else {// success ---- record username = _ usernameField. text; _ contBgView. hidden = YES; // hide on the login page // display _ tableView on the message page. hidden = NO; _ sendView. hidden = NO ;};}// registered user-(IBAction) registerAction :( UIButton *) sender {// register the page controller registerViewController * Ctrl = [[registerViewController alloc] init]; [self presentViewController: Ctrl animated: YES completion: ^ {;}]; // block callback (get the registration page, username, password) Ctrl. myBlock = ^ (NSString * textNum, NSString * textPassWord) {// resiger-registration mark NSString * dataStr = [NSString stringWithFormat: @ "{\" doWhat \": \ "resiger \", \ "username \": \ "% @ \", \ "password \": \ "% @ \"} ", textNum, textPassWord]; NSData * data = [dataStr dataUsingEncoding: NSUTF8StringEncoding]; // send a registration request to the server and listen to the request information [_ socket writeData: data withTimeout:-1 tag: 0]; [_ socket readDataWithTimeout:-1 tag: 0] ;}}// send a message to the server-(IBAction) sendMessage :( UIButton *) sender {if (_ message. text. length> 0) {// The message NSDictionary * dic = [NSDictionary dictionary]; dic ={ @ "socket": @ "client ", @ "username": username, @ "message": _ message. text}; [dataArr addObject: dic]; // insert data to the last cell NSIndexPath * index = [NSIndexPath indexPathForRow: dataArr. count-1 inSection: 0]; [_ tableView insertRowsAtIndexPaths: @ [index] withRowAnimation: Updated]; // scroll to the last cell [_ tableView scrollToRowAtIndexPath: index atScrollPosition: animated: YES];/* (content includes: Content tag, current client user name, whether it is a client, sent content) can of course be customized, as long as the server side receives the corresponding message, you can */NSString * message = [NSString stringWithFormat: @ "{\" doWhat \ ": \" message \", \ "username \": \ "% @ \", \ "socket \": \ "client \", \ "message \": \ "% @\"}", username, _ message. text]; NSData * data = [message dataUsingEncoding: NSUTF8StringEncoding]; // send a chat message to the server [_ socket writeData: data withTimeout:-1 tag: 0]; [_ socket readDataWithTimeout:-1 tag: 0]; _ message. text = @ "" ;}}# pragma mark-UITableView dataSource delegate-(NSInteger) tableView :( UITableView *) tableView numberOfRowsInSection :( NSInteger) section {return dataArr. count;}-(UITableViewCell *) tableView :( UITableView *) tableView cellForRowAtIndexPath :( NSIndexPath *) indexPath {static NSString * intenty = @ "UITableViewCell"; MyCell * cell = [tableView preview: intenty]; if (cell = nil) {cell = [[[NSBundle mainBundle] loadNibNamed: @ "MyCell" owner: self options: nil] lastObject];} NSDictionary * message = dataArr [indexPath. row]; // submit the model to the view to display the cell. message = message; return cell;} # pragma mark-AsyncSocketDelegate // 1. protocol method called by the client to connect to the server-(void) onSocket :( AsyncSocket *) sock didConnectToHost :( NSString *) host port :( UInt16) port {// listen to the server socket message [sock readDataWithTimeout: -1 tag: 0];} // 2. accept data sent from the server (read data)-(void) onSocket :( AsyncSocket *) sock didReadData :( NSData *) data withTag :( long) tag {// The server processes the messages sent by the client, and the corresponding return client can recognize other messages (for example, the above client sends dictionary messages to the server, and the server also returns the corresponding dictionary messages) NSDictionary * dic = [NSJSONSerialization JSONObjectWithData: data options: NSJSONReadingMutableLeaves error: nil]; // NSLog (@ "% @", dic); NSString * dowhat = [dic objectForKey: @ "doWhat"]; // content mark NSString * type = [dic objectForKey: @ "type"]; // processing result if ([dowhat isEqualToString: @ "commit"]) // return message for login verification {if ([type integerValue] = 1) {NSLog (@ "Verification Successful"); _ block (YES );} else {NSLog (@ "Verification Failed") ;}} else if ([dowhat isEqualToString: @ "resiger"]) // return message for registration {if ([type integerValue] = 2) {NSLog (@ "registered successfully");} else {}} else if ([dowhat isEqualToString: @ "message"]) // The message returned by the chat message {// get the message sent by another client, NSString * message = [dic objectForKey: @ "message"]; NSString * fromusername = [dic objectForKey: @ "username"]; // NSString * socket = [dic objectForKey: @ "socket"]; dic ={ @ "socket ": @ "server", @ "username": fromusername, @ "message": message}; [dataArr addObject: dic]; // place the UI operation on the master thread dispatch_async (dispatch_get_main_queue (), ^ {// insert data to the last cell NSIndexPath * index = [NSIndexPath indexPathForRow: dataArr. count-1 inSection: 0]; [_ tableView insertRowsAtIndexPaths: @ [index] withRowAnimation: Updated]; // scroll to the last cell [_ tableView scrollToRowAtIndexPath: index atScrollPosition: animated: YES] ;}) ;}// continue listening for messages sent from the server [sock readDataWithTimeout:-1 tag: 0] ;}@ end
On the registration page, when the view returns to the login page, remember to use Block callback.
// Call -- first judge if (self. myBlock! = Nil) {self. myBlock (_ fieldNum. text, _ fieldPassWord. text );}
// Determine whether the message is sent by itself in the layout subview. if ([what isecontostring: @ "client"]) {_ iconImage. frame = CGRectMake (Kw-50, 10, 40, 40); _ bgImage. frame = CGRectMake (Kw-50-(size. width + 30)-10, 10, size. width + 30, size. height + 30); _ contText. frame = CGRectMake (Kw-50-size.width-30, 20, size. width, size. height); _ usernameLabel. frame = CGRectMake (Kw-70, 1,100, 17);} else if ([what isecontostring: @ "server"]) {_ iconImage. frame = CGRectMake (10, 10, 40, 40); _ bgImage. frame = CGRectMake (60, 10, size. width + 30, size. height + 30); _ contText. frame = CGRectMake (80, 20, size. width, size. height); _ usernameLabel. frame = CGRectMake (52, 1,100, 17 );}
The Cell Layout determines the Layout Based on the sources of messages in the dictionary.
The socket Client is introduced here.