Developers don't lie to developers. You told me it was only $100?

Introduction

The 2021 Tencent game annual conference was held online. This year, with the strategic concept of "super digital scene" as the core, the press conference conveyed constructive thinking on game cognition and industrial boundary, and demonstrated the rich experience and diversified value brought by Tencent games to players through the centralized release of more than 60 game products and contents.

This press conference again selected cloud development CloudBase as one of the technology selection, realized the real-time bullet screen system at a very low cost, ensured stable operation, and brought high-quality interactive experience to game lovers. The following will focus on the whole process of the project team using cloud development to realize the barrage function.

"Attention of all departments, high energy ahead!"

1, Business background

The 2021 Tencent game annual conference has developed an exclusive applet, including live broadcast, lucky draw, viewing and playback. All bullet screen functions are based on the real-time data push of cloud development.

Before the technical selection of the barrage function, the development students sorted out the business scenarios:

  • Barrage real-time interaction
  • Allow a small amount of barrage to be lost
  • Only used on the night of the press conference live broadcast
  • Sensitive information / keyword filtering

After comprehensively considering the cost, stability, adaptability to small programs and other aspects, the project finally chose the real-time data push function of cloud development as early as At last year's press conference , the project team used the real-time data push of cloud development to realize the functions of live program list progress reminder. On this basis, the bullet screen was also uniformly moved to cloud development.

2, Technical practice

Development ideas

At first, I wanted to directly monitor the barrage collection of all users, but the official limit is that a single monitoring data cannot be greater than 5000, and the more monitoring data pieces, the worse the initialization performance. If it exceeds the upper limit, an error will be thrown and the monitoring will be stopped. Finally, the design is as follows: the user's bullet screen is inserted into set a and monitors data set b. the bullet screen is merged regularly by using the timer of cloud function and updated to the corresponding data record being monitored (as shown in the figure).

This ensures a constant number of data records monitored by the user. Here, 10 records (circular array) are used to summarize the barrage data, and all barrages of the current timestamp are updated to the data record with index = timestamp%10 every second. At the same time, the barrage refresh rate is fixed to 1s, reducing the performance consumption of continuous callback / rendering due to frequent data changes at the front end.

Code demonstration

Code of bullet screen sent by user:

exports.main = async (event, context) => {
// ... omit some authentication / blacklist / verification content security logic
let time = Math.ceil(new Date().getTime() / 1000);
// Insert barrage
let res = await db.collection('danmu_all').add({
data: {
openid,
content,
time,
},
});
return {err: 0, msg: 'ok'};
};

Barrage merging:

exports.main = async (event, context) => {
// ... omit some non critical code
// Only 100 of them are taken, which can be dynamically adjusted
let time = Math.ceil(new Date().getTime() / 1000) - 1;
const result = await db
.collection('danmu_all')
.where({time}).limit(100).get();
let msg = [];
for (let i of result.data) {
msg.push({
openid: i.openid,
content: i.content,
});
}
// Update the corresponding position of the circular array
db
.collection('watch_collection')
.where({index: time % 10})
.update({
data: {msg,time},
});
return msg;
}

When the front end processes the message notification, be careful not to repeat the watch. If the anonymous login of cloud development is turned on, the page at H5 can also use the synchronous barrage function:

this.watcher = db.collection('watch_collection').watch({
onChange: function(snapshot) {
for (let i of snapshot.docChanges) {
// Ignore non updated information
if (!i.doc || i.queueType !== 'update') {
continue;
}
switch (i.doc.type) {
// ... omit other types of message processing
case 'danmu':
// Barrage rendering
livePage.showServerBarrage(i.doc.msg);
break;
}
}
},
});

So far, the core function of the whole barrage has been fully realized.

Quadratic optimization

After running for a period of time, it is found that the barrage of several seconds is occasionally discarded. Later, check the execution log. It is found that even if the timer is configured to execute once per second, it is not strictly executed once per second in actual production. Sometimes it will skip 1-3 seconds. Here, redis is used to mark the current processing progress, even if there are skipped seconds, You can also backtrack the unprocessed time for supplementary recording. You can view the official tutorial on using redis for cloud functions redis tutorial for cloud functions.

The user sends the code of bullet screen part and adds the mark code:

exports.main = async (event, context) => {
// ... omit some authentication and verification content security codes
// ... omit insert code

// Mark merge task
await redisClient.zadd('danmu_task', time, time+'')
};

Bullet screen merging. Note: only those above redis5.0 can support zpopmin command. If you need to buy, you need to select the right version.

exports.main = async (event, context) => {
//Current seconds
let time = Math.ceil(new Date().getTime() / 1000) - 1;

while (true) {
// Pop up the smallest task
let minTask = await redisClient.zpopmin('danmu_task');
// There are currently no tasks
if (minTask.length <= 0) {
return;
}
// For the task in the current second, plug back and end
if (parseInt(minTask[0]) > time) {
redisClient.zadd('danmu_task', minTask[1], minTask[0]);
return;
}
// Perform merge tasks
await danmuMerge(time);
}
};

In terms of security logic, certain strategies are also made, such as rendering the sent barrage locally first. When the client receives the barrage push, it judges that the openid is not rendered when it is itself, so that even if the user's Barrage is filtered, it can be displayed locally and retain a certain user experience.

In addition, the upper limit of an instance of a single cloud function is 1000. If it is determined that the traffic is large that night, you can consider sharing the traffic with multiple cloud functions.

Implementation of management background

At the same time, the watch function can be used to synchronize the management background and refresh the bullet screen of the client in real time, so as to achieve the purpose of management. The same code can be reused at the front end and the management end:

Excerpt management background code:

methods: {
stop() {
this.watcher.close();
},
},
beforeDestroy() {
this.watcher.close();
},
mounted() {
this.app = this.$store.state.app;
this.db = this.app.database();
let that = this;
this.watcher = this.db.collection('danmu_merge').watch({
onChange(snapshot) {
for (let d of snapshot.docChanges) {
for (let v of d.msg) {
that.danmu.unshift(v);
}
}
if (that.danmu.length > 500) {
that.danmu = that.danmu.slice(0, 499);
}
},
});

The read permission setting of the collection also takes effect in the real-time data push. If the permission is set to only read the user's own data, the data not created by the user cannot be monitored during listening.

Tips

At that time, I didn't notice the restriction of watch on the database permission. By default, the database permission is only readable and writable by the creator. The first initialization of the circular array is created on the client during the development process. By default, the openid of the current user is added, so that other users can't read the data of the merge. Solution: delete the openid field or set the permission to be readable by all people.

The read permission setting of the collection also takes effect in the real-time data push. If the permission is set to only read the user's own data, the data not created by the user cannot be monitored during listening.

3, Project results and value

Based on the cloud function, real-time data push, cloud database and other capabilities developed by the cloud, the project runs smoothly throughout the whole process. Even at the peak traffic on the night of the press conference, the writing and operation of the barrage is stable. In terms of monitoring (reading), the performance of watch can stably support millions of online at the same time.

Finally, the two R & D personnel completed the development and commissioning of the barrage system in only two days. In terms of cost, the total cost of supporting the operation of the barrage system of the whole project is only about 100 yuan, mainly focusing on database reading and writing and cloud function call (at present, the function of monitoring database real-time data is in the free stage, and the cost of database reading will not be calculated). Excluding the cost of other modules, the actual barrage module may only consume dozens of yuan, The cost is much lower than expected, which is more than dozens of times lower than that of traditional instant messaging.

In general, the project adopts cloud development and has the following advantages:

  • With elastic expansion and contraction capacity, it can resist instantaneous high concurrent traffic and ensure the smooth progress of live broadcasting;
  • The cost is cheap. Only cloud function calls and database reading and writing fees are charged. Real time data push is free to use, which is very suitable for the project;
  • Secure and stable. The access of the project is based on the wechat private link developed by the cloud to ensure security;
  • It has a high degree of freedom and can fit other development frameworks and services.

Posted by Sentosa on Wed, 24 Nov 2021 08:34:33 -0800