preface

I admire those who write good articles very much. I have thought for a long time about how to write this article, how to name it, how to arrange the content, and even how deep each content should be. Can I make myself understood? In my usual style: not only to their own understanding, to write the article to let others understand; I did the same thing to see if I really understood. So I’m going to explain it slowly, and I’m going to ask you to take some time to read it.

Writing reason

I was lucky enough to become a programmer 2.5 years ago, and since then I have been able to change the world in a small way.


Funny. JPG
Salted fish
here
share

This article has a very clear guide for beginners, tell beginners to project directory structure, interface writing skills, permissions, responsibilities, coding specifications and some coding experience worth learning; However, for middle and advanced programmers, this article may be of no use at all, because most of the programmers at this stage have their own programming ideas, so WHEN I read this article two years later, I think it is useless, so there is a reason for the negative comments.Copy the code


Is skin. JPG

purpose

One’s own wish


Can’t help it. JPG

Improve yourself


There are ideal programmers

A platform for people who want to learn about sockets

When I learned Socket, I found some relevant articles on the Internet, such as: a beginner IM is enough, iOS instant messaging, from entry to “give up”? Such as excellent articles, for a person who does not understand Socket chat after reading the same confusion: how do I start to do it? Yes, these articles are either too deep or too simple to do real work. So NOW I do a Socket chat project, because it is version 1.0.0, so the code is very little, just the general appearance of the work out; Believe you from this time to participate in the project can really do, really to achieve a set of chat system.


Shameless. JPG

Ask for help

The workload of making a chat system is very huge, such as text and voice message sending, blacklist and other relationship processing, single chat, group chat, discussion group and other types of chat; So I need to use the power of open source to find a group of people who are willing to work together, and we can discuss and design the whole system together. The whole system is divided into C terminal and S terminal; S terminal does message forwarding and storage, but there is little emphasis on the design of S terminal, SO I consider using the original C to act as S (mainly because I don’t know Node.js and other languages, it would be best if I could find someone to implement S in Node.js or other languages) :

1. Language is just a tool. 2. Our design focus is on the C end; 3. Knowing the server logic can help us better understand the whole chat process. 4. C and S are both familiar OC languages without any language barrier; 5. Everyone has a complete system, which is convenient for debugging and development. 6: Not dependent on other developers, completely independent.Copy the code


Waiting for the big guy. JPG

How to participate in the project

I have hosted project 1.0.0 on Github and can now participate in the project as follows: 1: forkC and S-side source code switch to the corresponding branch for development:

1: Master is an interactive, fully functional master branch; 2.1.0.0 dev, 1.0.1dev, etc., are cloned from the master branch, used for the development of the corresponding version of the new function; I created these branches, so you just have to keep track of the current version; 3: Each development version can be merged into the main branch only after bug modification and function development is completed, which is a small convention; 4. There is no separate branch for bug modification. Considering the complexity, external interference should be minimized.Copy the code

So when we’re done with New Push Request, I’m Agreen; 2: Join the group (289092194 add group reason to write Sokcet learning communication, my personal information in the group number is iOS communication group, you can also add) to discuss, design and development. Of course, if no one really wants to work with me, I’ll stick with it. For those who want to participate in this project, I have the following requirements:

1: The code should be standardized, and I have put the specification document in the project; The purpose of this is to maintain a uniform style, so that other people can quickly understand; 2: comments should be complete, the code is for people to see; 3. You should have some iOS development experience; 4. Try to write unit-testable code; 5: Try to stand in the engineer's point of view to write code, performance, speed and memory can be properly considered; 6: The pursuit of quality rather than speed, the company is always catching up with the schedule, here you can show your code to others; 7: Look at other people's code with appreciation.Copy the code

What you should know about chat systems

TCP/IP protocol family


The OSI and TCP/IP. PNG

The Internet layer is also called the network layer. Network interface layer also has other names: data link layer, link layer, etc. I hope you know which layer to refer to.Copy the code

When we refer to TCP/IP, we generally refer to the TCP/IP four-layer model. TCP is only a protocol of the transport layer, and IP is only a protocol of the Internet layer. TCP/IP is a set of rules that define data transmission at the hardware level. The purpose of this set of rules is to allow different types of data to be processed and transmitted through different transmission media from the source address to the destination address.

Select TCP or UDP as the transport protocol

This is an inevitable problem, and we do not need to discuss it here. Years of practical experience in the industry have concluded that:

1: the team is awesome, using UDP or UDP+TCP; 2: The team generally uses TCP.Copy the code

So we use TCP as the transport protocol for our chat system.

TCP and IP


Relationship between some protocol layers. PNG




TCP segment. PNG

PNG IP datagrams
As far as possible to
here

Three-way handshake and four-way wave during TCP connection

This part please read this good article, after reading I come to the summary:

Three-way handshake: when our own assembly (please pay attention to understand the word) format shaking hands with TCP segment to meet for the first time, sent to the destination, the destination if support TCP connection, it will reply to you the second hand information, did you receive the second hand information put in the past the third handshake format TCP segments completes the connection operation; Four waves: Similar logic.Copy the code

Why you need three handshakes and four waves here; We can encapsulate TCP segments ourselves to simulate a three-way handshake like this buddy article; Of course, you can also learn how Charles grabs Https.

Socket

As mentioned above, if we want to use TCP protocol to transfer data, we need to understand messages, segments, frames, handshakes and waves, even IP sharding, timeout retransmission and sliding window, etc., let us implement too much trouble. Socket has helped us to do all this, we just need to use the Socket interface can be provided, which specific interface can see here. You might still be bothered by all this. That’s why CocoaAsyncSocket is a three-party library that hides troublesome Socket operations from users and provides object-oriented OC interfaces to users. So this system also uses CocoaAsyncSocket for secondary encapsulation.

What is the Socket custom protocol

We can use the GCDAsyncSocket class in CocoaAsyncSocket to transfer data using TCP, GCDAsyncUdpSocket class can transfer data using UDP; That is, transport control layer and below the protocol we are not able to customize, so our custom protocol is naturally defined user layer protocol.

Implement chat existing common user layer protocols

If you don’t want to customize the user layer protocol, you can select the existing user layer protocol from here and develop directly using the provided SDK. Of course, the chat system is divided into C and S, as mentioned earlier, our S is also used by C (again, to clarify).

The content of this system agreement is explained in part

There is not much to talk about here, because you can download the source code directly, now 1.0.0 version of the code is very small, you can write the connection, login, heartbeat process to understand the whole project content; If you say you don’t understand sockets, you probably haven’t learned them yet.

I don't mean this in any bad way, because everything is learned step by step, and it's counterproductive to absorb what you can't master at what stage.Copy the code

Package format Definition

When we send data, let’s say we send a piece of data “Hello world”, maybe the destination receives two pieces of data” Hello “and “world”, so we need to subcontract; Reasons for subcontracting:

1: Ethernet is limited to 46-1500 bytes. 1500 is the MTU of Ethernet. TCP sets an offset for IP packets to be fragmented for transmission. 2: The size of the router can also be set.Copy the code

When we send data, for example, we send two pieces of data “hello “and “world”, maybe the destination receives only one piece of data” Hello world”, so we need to glue packets; Part of the reason for sticking package:

1: TCP To improve transmission efficiency, the sender sends a piece of data only after collecting enough data. If a small amount of data is sent for several consecutive times, TCP usually combines the data into a packet based on the optimization algorithm and sends the packet once. In this way, the receiver receives sticky packet data.Copy the code

Since TCP/IP is intended to provide as reliable a transmission as possible, packets may be lost or wrong packets may be received during transmission, so we also need to perform error packet handling. All three problems can be solved by adding a header to the sent data, as seen in the project IMSocketHeader; At present, only 4 flag bits are placed in the packet header with 4 bytes, and each flag bit occupies 1 byte:

1: version Puts the current version of the user's chat system, which can be used when new functions are released in the later chat. Some functions are not enabled in the old chat version. 2: magic_num is used to determine if the package is a package we should process. 3: Command stores different types of commands, such as heartbeat and login, because different packages are processed in different ways by clients and servers. 4: body_len Content length, used to process sticky and subcontract packages to a complete package, the detailed processing process is seen in IMSocketIO.Copy the code

Why sticky, subcontract, and error packets are handled:

Just to get a complete parsing unit, that is, a complete package (header + content) that we defined.Copy the code

The data format

By adding a packet header, the data we throw to the TCP layer becomes: packet header + content; So what format do we send content in? So here we’re taking the object that we’re sending and turning it into a JSON string and turning it into NSData and sending it. – Protobuf was not chosen for the following reasons:

- Not everyone who wants to work on the project will be able to install and use the Protobuf environment; 2: Data format is not important in the whole system design, it belongs to the later optimization content; 3: We are more familiar with JSON, which is faster and more convenient to use.Copy the code

Important classes in some projects

In fact, the connection, login and other processes in the project have used up all the classes in the project, you can follow the steps to go through the process to know the role and significance of each class. But there are a few core classes that need to be singled out.

IMSocketModules

Messages to be received are registered in this class. Unregistered messages are automatically discarded. This is a bit like an MQTT.

IMSocketControl

Timeout retransmission, heartbeat, data encryption and decryption, and received unregistered messages are discarded in this class.

Brief introduction to the server project

1: rapid construction by foundation engineering; 2: The project is mainly a ChatSocketServer class used to receive the client connection, login, logout, heartbeat and other requests, the reason for using a file because the system is focused on the client; 3: Because chat is independent of the application module, the server does not authenticate the login user, that is, any client whose login information is legitimate will establish a connection with the server. The database uses Realm to cache messages. 5: Version iteration content is updated in real time in readme.md of the project.

A brief introduction to the client project

1: rapid construction by foundation engineering; 2: Three dead users have been simulated in the current application. The registration function will be considered in the future, but it is not available at present. 3: There is a simple UITabBarController as the main controller, there are three interfaces: session, friends, ME; At present, only user information is displayed in my interface, and other interfaces are slowly iterated behind. 4: You can see ChatMineController, which is also based on Andoird, because I’m an Android developer myself, and I recently decided to try out the feasibility of developing an interface like this. Of course you can use MVP, MVVM, etc. in your modules when you are working on a project; Realm addNotificationBlock is used to update the database driver interface. 6. Create the corresponding files in SocketIMDemoTests and the corresponding folder of the main project for unit tests; 7: Version iteration content is updated in real time in readme.md of the project.

At the end of the article


Come on. JPG

The worst case scenario is that at the end of the day (tentatively scheduled to start work on 1.0.1dev by the end of March 2018) it’s still just me, so I’ll keep writing it, but the iteration cycle will be much longer.