Goim Article Series (5 articles in total):

  • Goim architecture and customization
  • From goIM customization, talk about golang interface decoupling and gRPC
  • Basic concepts and applications of Bilibili/Discovery (Eureka) in GOIM
  • Goim data Flow Data flow
  • Goim business Integration (Sharing session summary and QA)

There is a Slack channel where many people talk about Goim. Welcome to Slack #goim

Goim. IO is a very successful IM (Instance Message) instant messaging platform. This paper introduces data definition and data flow in GOIM

1. Data Flow in GOIM

1.1 Data flow in architecture

Look at the picture

The data flow

  1. The HTTP interface sends data to Logic
  2. Logic takes session data from Redis, serializes it with protobuf, and sends it to MQ
  3. The job subscribes data from MQ and takes server/room from im send data and sends data to Comet on the specified server
  4. Comet receives data sent by a job, stores it in the ring buffer of a specified channel, converts it into TCP/WebSocket packets, and sends them to the client of a specified channel

1.2 Simplified data flow details

The diagram above illustrates the key data structures in GOIM:

  1. Note that this data structure is serialized by Logic as protobuf and sent to MQ, deserialized in job and distributed to Comet
  2. Session information, mainly the correspondence between mid ->server and room- >server, is stored in Redis
  3. After the IM information in comet is serialized from MQ by job, the SERVER, room, and keys(one or more keys corresponding to channels) are extracted and sent to the specified Comet server
  4. Comet encapsulates data packets using TCP/WebSocket and sends them to the end user

2. Data definition in GOIM

2.1. Logic Sends IM messages

Publish IM message definitions (defined in Protobuf)

message PushMsg {
    enum Type {
        PUSH = 0;
        ROOM = 1;
        BROADCAST = 2;
    }
    Type type = 1;
    int32 operation = 2;
    int32 speed = 3;
    string server = 4;
    string room = 5;
    repeated string keys = 6;
    bytes msg = 7;
}
Copy the code

2.2 Session Data

When a TCP client or websocket client connects to a Comet Server, Comet uses gRPC to communicate internally with Logic to generate session data, which is stored in Redis

When the HTTP client sends an IM message to Logic, Logic queries the session data to Redis. For the existing room- > server/mid (memberID) -> server, logic sends the message to MQ. This part of the code is relatively clear and will not be explained

2.3. TCP/WebSocket packet definition

Push IM messages. The object name is Proto, which is defined in Protobuf

message Proto {
    int32 ver = 1 [(gogoproto.jsontag) = "ver"];
    int32 op = 2 [(gogoproto.jsontag) = "op"];
    int32 seq = 3 [(gogoproto.jsontag) = "seq"];
    bytes body = 4 [(gogoproto.jsontag) = "body"];
}
Copy the code

Protobuf file github.com/Terry-Mao/g… In line 12

TCP/websocket packet group operating in/API/discount package/comet/GRPC/protocol. Go

As can be seen from the figure above, goIM is defined in TCP /websocket packet, and PROto is defined in GO, more than two fields, total packet length/packet header length

3. Comet processing

Simplify the data flow from the sending end to the receiving end. It can be seen that serverID/roomID/Channel (indicated by mid or key) is mainly used for shunting/distribution, and these three fields are not included in the final push packet.

At the same time, Comet uses ring Buffer to cache multiple messages sent by a channel and push them to the terminal. Here, we do not see much processing of the messages sent by the push.

_

_


Look at the code and fill in the details

// Channel used by message pusher send msg to write goroutine.
type Channel struct {
	c        *conf.CometConfig
	Room     *Room
	CliProto Ring
	signal   chan *grpc.Proto
	Writer   xbufio.Writer
	Reader   xbufio.Reader
	Next     *Channel
	Prev     *Channel

	Mid      int64   // ######### memberID
	Key      string
	IP       string
	watchOps map[int32]struct{}

	mutex sync.RWMutex
}
Copy the code

Here:

  1. Mid is memberID, which user is connected to the current channel. The long connection uses the key as the session id of the long connection. In other words, A key specifies which im message should be sent to which users on the other end of an online long connection
  2. The key is the sessionID of the long connection
  3. WatchOps is a map where int32 is the room number. WatchOps is used by the current persistent user to listen for im notifications from which rooms the current client is receiving. To put it another way, a goIM terminal can receive IM messages from multiple rooms
  4. WatchOps initialization is handled when a TCP/WebSocket client makes its first connection, depending on the code for details.

_

_

After obtaining the published IM information from the POST request of Logic from HTTP, it is serialized and sent to MQ. Then, it is unpacked and deserialized in job, and then it is composed of packets. Whether this step has any impact on the performance needs to be determined by sending test data.

4. Summary

Above, should open source community friend request, has made a simplified analysis to the internal data structure, spend not much, the level is limited, or has considered improperly or the analysis is improper, welcome the criticism and comment.

Finally, goim. IO has posted many articles on the Internet, which have inspired me. Thank you.

Recommend the following articles:

  • Alexstocks. Making. IO/HTML/im. HTM… Great article by AlexStcks, thoughtful and thoughtful
  • Github.com/LinkinStars… By LinkinStars, this is worth a look
  • Moonshining. Making. IO / 2018/03/09 /… It’s very carefully written

Once again, thank youwww.bilibili.comOpen source &Mao JianAnd the many predecessors of the open source community, friends

_

About me

Online name Tsingson (Sanmingzhi, known as Uncle 3)

Original Ustarcom IPTV/OTT Business Unit Broadcast control product line Technical architecture Wet/solution engineering Wet role (8 years), freelancer,

Like music (harmonica, one of the main planners of the 3rd / 4th / 5th Guangdong International Harmonica Carnival), photography and cross-country,

Golang language (postgres + Golang for commercial projects)

_

Written by Tsingson in Shenzhen, China, Xiao Luo Harmonica Music Center, 2019/05/07