Build a Real‑Time Bullet‑Screen App with Serverless WebSocket and Tablestore in 2 Minutes
This guide shows how to create a full‑duplex bullet‑screen (barrage) application on Alibaba Cloud using Serverless architecture, API Gateway, Function Compute, OSS and Tablestore, covering the overall design, data model, step‑by‑step deployment, and essential code snippets.
Overview
The article presents a Serverless solution for full‑duplex (WebSocket‑like) communication using a bullet‑screen (barrage) scenario. By combining DNS, API Gateway, Function Compute, OSS and Tablestore, the system delivers real‑time interaction without long‑running services.
Architecture
The request flow is DNS → API Gateway → OSS | Function Compute . Three static‑resource projects are built, while the function layer mixes event‑driven and HTTP triggers. Tablestore provides persistent storage.
Components
The application consists of three client types—big screen, individual user, and administrator—plus a device‑registration service and an API service. The gateway maintains long‑lived connections; each client registers a device ID, which triggers a registration function that stores the ID in Tablestore.
Data Model
equipment (device information)
barrage (bullet messages)
interceptor (filter rules)
Preparation
Obtain a domain name and configure Alibaba Cloud DNS.
Enable API Gateway, Function Compute, OSS, and Tablestore services.
Install Serverless Devs (CLI or Desktop) and ensure the required products are available.
Key Configuration Parameters
Secret alias – Alibaba Cloud account credential.
Domain – custom domain for the API.
bucketName – OSS bucket name.
endpoint – public address of the Tablestore instance.
instance – Tablestore instance name.
Deployment Process
Using Serverless Devs, initialize the project. The tool creates Tablestore tables, writes configuration to s.yaml, and then deploys front‑end assets, the registration function, the API function, and configures gateway routing and domain binding.
Database Initialization and CRUD Operations
The initializer loads credentials and creates a global tableClient for later use:
exports.initializer = (context, callback) => {
try {
const ak = context.credentials.accessKeyId;
const sk = context.credentials.accessKeySecret;
const stsToken = context.credentials.securityToken;
SAT.init(endpoint, instance, ak, sk, stsToken);
internal = { tableClient: SAT, TableStore };
callback();
} catch (err) {
callback(err.message);
}
};Typical CRUD examples (using the SAT wrapper):
// Single primary‑key query
const getInterceptor = async (ctx) => {
const { tableClient } = ctx.req.requestContext.internal;
const res = await tableClient.table('interceptor').get(1, []);
return res;
};
// Query all equipment
const getAllEquipment = async (tableClient, TableStore) => {
const res = await tableClient.table('equipment').getRange(TableStore.INF_MIN, TableStore.INF_MAX, []);
return Object.keys(res).map(key => res[key]);
};
// Insert barrage (composite primary key)
const addBarrage = async (ctx) => {
const { tableClient, TableStore } = ctx.req.requestContext.internal;
const { fromId, fromName, color, fontSize = '28px', checkStatus = 0, message } = ctx.request.body;
const now = Date.now().toString();
const data = { fromId, fromName, color, fontSize, checkStatus: parseInt(checkStatus), message, sendTime: now, checkTime: now };
const res = await tableClient.table('barrage', ['gid', 'id']).put([1, TableStore.PK_AUTO_INCR], data, 'I');
return res;
};
// Update barrage status
const updateBarrage = async (ctx) => {
const { tableClient } = ctx.req.requestContext.internal;
const { checkStatus } = ctx.request.body;
const { id } = ctx.request.params;
const now = Date.now().toString();
const res = await tableClient.table('barrage', ['gid', 'id']).update([1, parseInt(id)], { checkStatus: parseInt(checkStatus), checkTime: now }, 'I');
return res;
};
// Conditional query (e.g., fetch unchecked messages)
const getBarrageByCondition = async (ctx) => {
const { tableClient, TableStore } = ctx.req.requestContext.internal;
const res = await tableClient.table('barrage').search('index', ['checkStatus', 0]);
return res;
};Result Verification
After deployment, accessing the custom domain (e.g., barragego.serverless-developer.com) displays the live bullet‑screen UI. If the domain binding fails, manually bind the API Gateway domain to the OSS domain as shown in the screenshots.
Conclusion
The project demonstrates how Serverless can implement WebSocket‑style full‑duplex communication. The pattern can be extended to chat rooms, collaborative platforms, or any scenario requiring real‑time data push. Source code is available for further customization.
References
https://github.com/Serverless-Devs
https://github.com/devsapp/start-barrage
https://wanwang.aliyun.com/domain/dns
https://www.aliyun.com/product/apigateway
https://www.aliyun.com/product/fc
https://www.aliyun.com/product/oss
https://www.aliyun.com/product/ots
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Alibaba Cloud Native
We publish cloud-native tech news, curate in-depth content, host regular events and live streams, and share Alibaba product and user case studies. Join us to explore and share the cloud-native insights you need.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
